Drzewo kategorii – funkcja rekurencyjna
W wielu serwisach mamy do czynienia ze złożoną strukturą kategorii, często nie jesteśmy w stanie z góry założyć ile będzie zagłębień podkategorii. Załóżmy, że chcemy zbudować drzewo kategorii w takim serwisie. Sprawa niby banalna, jednak nadal znajduję w sieci funkcje, które wywołują zapytania do bazy danych w pętli. Widziałem nawet rozwiązania korzystające z rekurencji, tyle że każde wywołanie funkcji wysyłało kolejne zapytanie by pobrać podkategorie. Rozwiązania takie, jak nie trudno się domyślić, mają tragiczny wpływ na szybkość działania serwisu.
Dlatego też zamieszczam funkcję, która tylko raz wysyła zapytanie do bazy, przyda się pewnie wielu początkującym programistom. W bazie danych mam tabelę kategorie, a w niej kolumny id, rodzic_id, nazwa, gdzie rodzic_id zawiera id kategorii nadrzędnej lub 0 jeśli jest to główna kategoria.
function drzewoKategorii ($kategorie = null, $rodzicId = 0, $zaglebienie = 0, $wynik = null) { if ($wynik == null) $wynik = array(); if ($kategorie == null) { $query = "select * from kategorie order by rodzic_id, nazwa"; $kategorie = DB::getAll($query); } foreach ($kategorie as $kat) { if ($r["rodzic_id"] == $rodzicId) { $r["zaglebienie"] = $zaglebienie; $wynik[] = $kat; $wynik = drzewoKategorii ($kategorie, $kat["id"], ($zaglebienie+1), $wynik); } } return $wynik; } |
Funkcję tę możemy wywołać bez parametrów, wtedy sama pobierze wszystkie kategorie z bazy danych, jeśli chcecie podać własną tablicę kategorii, pamiętajcie by posortować ją po polu rodzic_id, w przeciwnym razie funkcja nie będzie działać prawidłowo. Drugi parametr $rodzicId pozwala na stworzenie drzewa kategorii od podanego zagłębienia – wystarczy podać id kategorii dla której chcemy pobrać drzewo podkategorii. Pozostałe parametry nie powinny być wprowadzane.
Funkcja drzewoKategorii zwraca tablicę kategorii ułożoną w kolejności odpowiadającej strukturze drzewa. Dla ułatwienia wyświetlania, każda kategoria otrzymała pole zaglebienie, które określa poziom zagłębienie podkategorii (im większe tym bardziej zakorzeniona jest podkategoria).
Oto przykład użycia naszej funkcji do wyświetlenia drzewa kategorii:
$drzewo = drzewoKategorii(); foreach ($drzewo as $galaz) { for ($i=0; $i<=$galaz["zaglebienie"]; $i++) { echo '-'; } echo $galaz["nazwa"].'<br/>'; } |
Kategoria: php
17 komentarzy styczeń 3rd, 2009