
Sonsuz Kategori Alt Kategori Zinciri
İç içe kategorileri ya da menüleri Hepsiburada, Vatan Bilgisayar veya bunlar gibi çok fazla ürün çeşidi olan sitelerde görmüşsünüdür. Örneğin; Bilgisayar > Dizüstü Bilgisayar > Oyun Bilgisayarı gibi. Çok karmaşık gibi görünen bu yapıyı aslında tek bir SQL tablosu ve birkaç satırdan oluşan PHP kodu ile oluşturmak mümkün.
Bu yapıyı meydana getirmek için öncelikle SQL tablomuzu halledelim. SQL veritabanımızda kategoriler adında bir tablo oluşturuyoruz ve bu tabloya üç alan ekliyoruz;
- id - int (auto_increment, key)
- pid - int
- kategoriAdi - varchar(50)
Aşağıdaki linkten SQL dosyasını indirip çalıştırdığınız zaman hem kategoriler adında tabloyu oluşturmuş hem de içerisine verileri eklemiş olacaksınız.
SQL dosyasını indirmek için TIKLAYINIZ.
SQL dosyasını çalıştırdığınız zaman aşağıdaki tabloda kayıtların verilerin yer aldığı tablomuz oluşacaktır.
id | pid | katagoriAdi |
1 | 0 | Bilgisayar |
2 | 1 | Dizüstü Bilgisayarlar |
3 | 1 | Masaüstü Bilgisayarlar |
4 | 1 | Oyun Bilgisayarları |
5 | 2 | Casper Notebook |
6 | 2 | Asus Notebook |
7 | 4 | Monster Notebook |
8 | 4 | MSI Notebook |
9 | 0 | Yazıcılar |
10 | 9 | Lazer Yazıcılar |
11 | 9 | Mürekkep Püskürtmeli Yazıcılar |
12 | 9 | Tanklı Yazıcılar |
13 | 10 | HP Yazıcılar |
14 | 10 | Canon Yazıcılar |
15 | 13 | HP M Serisi |
16 | 13 | Canon AirPrint Serisi |
Bu tabloda yer alan pid değeri yani parent id değeri, o kategorinin bağlı bulunduğu üst kategorinin id değerini belirtiyor. Ana kategorilerin pid değeri ise 0 olarak belirlenmiş durumda.
Gelelim, iç içe kategorilerin listelenmesine. Bu yapıyı oluşturmak için recursion olarak tanımladığımı bir fonksiyon türü kullanacağız. Recursion, kendi içerisinde tekrar çağrılan yani yinelenen fonksiyon yapısıdır. Daha fazla bilgi için bu linkteki bilgileri gözden geçirebilirsiniz.
İşte iç içe sınırsız kategori listeyen fonksiyonumuz;
function kategoriListe($id)
{
global $con;
echo "<ul>";
$kod="SELECT
K.id, K.kategoriAdi,
(SELECT COUNT(A.id) FROM kategoriler AS A WHERE A.pid=K.id ) as altKategoriSayisi
FROM kategoriler AS K
WHERE K.pid={$id}";
$sql=mysqli_query($con,$kod);
while($veri=mysqli_fetch_assoc($sql))
{
echo "<li>".$veri["kategoriAdi"];
if($veri["altKategoriSayisi"]>0)
kategoriListe($veri["id"]);
echo "</li>";
}
echo "</ul>";
}
Dikkat ettiyseniz kategoriListe fonksiyonumuz, şarta bağlı olarak kendi içinde tekrar çağrılıyor. İşte bu yapının adı recursion fonksiyon yapısıdır. Koddaki $con değeri ise mysqli fonksiyonundaki bağlantı değişkenini ifade ediyor.
Aşağıdaki gibi fonksiyonumuzu çağırabiliriz;
kategoriListe(0);
İlk önce ana kategorileri listelemek için fonksiyonu çağırırken parametreye değer olarak 0 değerini gönderdik.
Bu kodları çalıştırdığınız zaman aşağıdaki yapı gibi bir çıktınız olacaktır;
- Bilgisayar
- Dizüstü Bilgisayar
- Casper Notebook
- Asus Notebook
- Masaüstü Bilgisayar
- Oyun Bilgisayarları
- Monster Notebook
- MSI Notebook
- Dizüstü Bilgisayar
- Yazıcılar
- Lazer Yazıcılar
- HP Yazıcılar
- HP M Serisi
- Canon Yazıcılar
- Canın Airprint Serisi
- HP Yazıcılar
- Mürekkep Püskürtmeli Yazıcılar
- Tanklı Yazıcılar
- Lazer Yazıcılar
Mysql veritabanımızda bulunan kategoriler tablomuza yeni kategori eklediğimiz zaman bu yapı otomatik olarak genişleyecektir.
Yazıyla ilgili soru ve görüşlerinizi yorum olarak yazabilirsiniz.
Hayırlı çalışmalar.
Daha iyi çözüm yolları var mıdır? Tabi ki vardır. Mesela aklıma gelenleri yazmak istiyorum.
1. Kategori zinciri çok sık değişen bir sayfa değil. Bu nedenle her seferinde kategori zincirinin SQL sorgusu ile yeniden oluşturulmasındansa menu.html adında statik bir sayfa oluşturulur. Kategori zincirinde meydana gelen her değişiklik sonrası (güncelleme, silme, ekleme) menu.html sayfası basit bir tetikleme sonrasında yeniden oluşturulur. Bu sayede belki de ayda bir iki kez SQL sorgusu çalıştırılmış olur.
2. yöntem olarak bu iş front-end tarafında yapılabilir. API isteği ile tüm kategoriler bir dizi içine alınıp, kategori > alt kategori front-end tarafında oluşturulabilir. Bu sayede tek SQL sorgusu ile bu iş bitmiş olur. Vue.js ön tarafta bu iş için ideal olabilir.
Akıl akıldan üstündür. Daha iyi fikri olan dostlar bu yorum altında yazarlarsa içeriği gören arkadaşlar için de güzel bir kaynak olmuş olur. :)