Author
Message
Kaan

Administrators

Online status

678 posts

#840   2016-02-01 00:00 GMT        
Php ve Mysql ile Etiket Bulutu Oluşturmak

Hemen hemen her sitede etiket bulutu ile karşılaşıyorsunuzdur.
Etiketler sitemizde yayınladığımız yazılarda yazılarımızı ifade ederler ve genelde bir kelimeden oluşurlar.

Etiket bulutu oluşturmak için elimizde etiketler ve bu etiketlerin kaç defa kullanıldığı bilgileri olmalıdır. Etiketlerin kaç defa kullandığı bilgisini etiketlerimizin yazı font büy
Kod:
**100624e6b8e25979a01
code]yazi_id
baslik
yazi[/code]
"etiketler" Tablosu

[code]etiket_id
etiket
yazi_adedi[/code]
"yazi_etiket_iliskileri" Tablosu

[code]page_id
etiket_id[/code]
Tablolarımız bu şekilde olac
:
ysql]CREATE TABLE `yazilar` (

    `yazi_id`  int(11) UNSIGNED NOT NULL AUTO_INCREMENT ,

    `baslik`  text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,

    `yazi`  text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,

    PRIMARY KEY (`yazi_id`)

);



CREATE TABLE `etiketler` (

    `etiket_id`  int(11) UNSIGNED NOT NULL AUTO_INCREMENT ,

    `etiket`  varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,

    `yazi_adedi`  int(11) UNSIGNED NOT NULL ,

    PRIMARY KEY (`etiket_id`)

);



CREATE TABLE `yazi_etiket_iliskileri` (

    `etiket_id`  int(11) UNSIGNED NOT NULL ,

    `yazi_id`  int(11) UNSIGNED NOT NULL

)

;
UNSIGNED NOT NULL
)
;[/highlight]
Sql kodumuzu yazmadan önce "etiketler" tablosundaki yazi_adedi adlı sütunu neden kullandığımız açıklamak istiyorum. Ben yazıyı eklerken kullandığım etiketin yazı adedini güncelleyerek etiketler tablosunda tutmayı tercih ediyorum böylece sql sorgumuz sistemi fazla yormadan hızlı bir şekilde gerçekleşecektir. Aksi taktirde etiketlerinin kullanım adedini almak için sorguda join kullanmamız gerekecekki bu da sorguyu yavaşlatacaktır. Fakat siz dersenizki ben yazı eklerken etiket adedeni güncellemekle uğraşamam yazi_adedi sütununu kaldırabilirsiniz. İsterseniz "yazi_adedi" sütunu kullandığımızda ve kullanmadığımızdaki sorgularımızı yazalım.

"yazi_adedi" sütunu olduğunda sql sorgusu
[highlight=mysql]SELECT etiket_id,etiket, yazi_adedi FROM etiketler
ORDER BY yazi_adedi DESC
LIMIT 10[/highlight]
"yazi_adedi" sütunu olmadığında sql sorgusu
[highlight=mysql]SELECT e.etiket_id,e.etiket, COUNT(*) AS yazi_adedi FROM etiketler AS e
INNER JOIN yazi_etiket_iliskileri AS yei ON k.etiket_id=yei.etiket_id
GROUP BY yei.etiket_id
ORDER BY yazi_adedi DESC
LIMIT 10[/highlight]
"yazi_adedi" sütunu kullanıp kullanmamak artık size kalmış olaydır.

Ben yine de "yazi_adedi" sütununu kullanacak olan arkadaşlarımız için yeni yazı elediğimizde veya güncellediğimizde o yazıya eklediğimiz etiketlerin yazi_adedi'ni güncelleyen sorguyu veriyorum.
[highlight=mysql]UPDATE etiketler as e SET yazi_adedi=(
SELECT COUNT(*)
FROM yazi_etiket_iliskileri as yei
INNER JOIN yazilar as y ON yei.yazi_id=y.id
WHERE yei.etiket_id=e.etiket_id
)
WHERE e.etiket_id IN ('16', '21')[/highlight]
Yazı adedini güncelleyen sorgmuzda where koşulunda vermiş olduğum '16' ve '21' değerleri yazıya eklemiş olduğumuz etiketlerin etiket id'dir yani sizin sorgunuzda değişecek olan kısım.

Etiket bulutu oluşturan php fonksiyonumuz.
[highlight=php]<?php

function etiket_bulutu($etiketler = array(), $ile_birlestir=' '){
$max_adet = 0 ;
//en çok kullanılan etiketin yazı adedini alıyoruz
foreach($etiketler as $index => $etiket)
{
if ($etiket['yazi_adedi'] > $max_adet)
$max_adet = $etiket['yazi_adedi'];
}
unset ($etiket);

$etiket_bulutu = array();
//Bütün etiketlerin font büyüklüğünü belirleyen for döngüsü
foreach($etiketler as $etiket)
{
//etiketin yazı adedini maksimum yazı adedine bölerek yüzdesini buluyoruz
$yuzde = ($etiket['yazi_adedi']/$max_adet)*100;

// Yüzde aralıklarına göre font büyüklüğü belirleniyor
if($yuzde >= 9 $size = 2.0;
else if($yuzde >= 80) $size = 1.7;
else if($yuzde >= 70) $size = 1.6;
else if($yuzde >= 60) $size = 1.5;
else if($yuzde >= 50) $size = 1.3;
else if($yuzde >= 40) $size = 1.1;
else if($yuzde >= 30) $size = 1.0;
else if($yuzde >= 20) $size = 0.8;
else if($yuzde >= 10) $size = 0.7;
else if($yuzde >= 5) $size = 0.7;
else $size = 0.7;

$etiket_bulutu[$etiket['etiket']] = '<a href="#etiket_linki" style="font-size: '.$size.'em" title="'.$etiket['yazi_adedi'].' adet yazı bulunmaktadır" >'.$etiket['etiket'].'</a> ';
}

ksort($etiket_bulutu); //diziyi key değerlerine göre sırala
return implode($ile_birlestir, $etiket_bulutu);
}[/highlight]
Bu fonksiyonumuz iki adet parametre alıyor. Birincisi etiket bulutu oluştururken kullanılacak olan etiketler, diğer parametremiz ise etiketlerin arasına koyulacak olan karakter.

Örnek Kullanım
[highlight=php]$etiketler = array(
array('etiket'=> 'etiket 1','yazi_adedi'=>5),
array('etiket'=> 'etiket 2','yazi_adedi'=>3),
array('etiket'=> 'etiket 3','yazi_adedi'=>1),
array('etiket'=> 'etiket 4','yazi_adedi'=>6),
array('etiket'=> 'etiket 5','yazi_adedi'=>10),
array('etiket'=> 'etiket 6','yazi_adedi'=>3)
);
echo etiket_bulutu($etiketler, ' ');[/highlight]
Ben fonksiyonun örnek kullanımında etiketler dizisini elle oluşturdum ama siz o etiketleri veritabanından çekip benim verdiğim örnekte kullandığım dizi haline getirip fonksiyona parametre olarak göndermelisiniz.


Bunlara baktınızmı?
Seditio Etiket (Tags) Sistemi
Seditio Site URL Adresi (Domain) Değiştirmek İçin Mysql Sorgular
Mysql Karakter Seti Değiştirme (Convert)
Kişiliğim, hayatım hakkında konuşabilirsiniz. Fikir yürüte bilirsiniz. Beni öyle böyle sanabilirsiniz. Ama emin olamazsınız. Sizin hakkımdaki yorumlarınız, sanmalarınız benim gerçek de ne olduğumu değiştirmez. Baktığım yeri söyleye bilirsiniz ama ne gördüğümü ASLA...