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

Kurs Mootools 1.2 (part 1) – selectors

Witam,

Prędzej czy później, każdy programista piszący kod w javascript zacznie szukać framework’a dla tego języka. Obecnie największą popularnością cieszą się JQuery i PrototypeJS. Ja wybrałem jednak Mootools, nie jest tak wielki (czytaj “ciężki”) jak wymienione wcześniej, a daje nam całkiem spory zasób funkcji, które ułatwią i przyspieszą programowanie w javascript.

W pierwszej części kursu zajmę się selektorami, czyli funkcjami, które zwracają obiekt lub tablicę obiektów w/g wyznaczonych przez nas kryteriów.

Zamiast żmudnego wklepywania document.getElementById('id') wystarczy wpisać $('id') by uzyskać ten sam efekt. Funkcja $ zwraca więc pojedynczy element, jeśli chcemy wyszukać kilka elementów możemy użyć $$ lub getElements. Obie funkcje jako parametry przyjmują maskę po której nastąpi szukanie, przy czym funkcję getElements wywołuje się na obiekcie i zwraca ona elementy znajdujące się w obiekcie.

Czas na przykłady:

?View Code JAVASCRIPT
//wszystkie elementy <div> na stronie
$$('div');
 
//wszystkie elementy <div> i <span> na stronie
$$('div', 'span');
 
//wszystkie radio buttony należące do formularza o id="id_formulaza"
$('id_formularza').getElements('input[type=radio]');
 
//wszystkie elementy <span> których id zaczyna się od "prefix"
$$('span[id^=prefix]');
 
//wszystkie elementy <span> których id kończy się na "sufix"
$$('span[id$=sufix]');

Przydatne również mogą okazać się selektory first, last i contains:

?View Code JAVASCRIPT
//pierwszy element w <tr>
$('tr:first-child');
 
//ostatni element w <tr>
$('tr:last-child');
 
//wszystkie divy zawierające tekst "szukany"
$$('div:contains("szukany")');

Oczywiście na tak pobranych elementach możemy wywoływać różne funkcje, np:

?View Code JAVASCRIPT
$$('div').setStyle('color', '#FF0000');

lub skorzystać z iteratora each i wykonywać złożone operacje na każdym elemencie, np:

?View Code JAVASCRIPT
$$('input[type=text]').each(function(element){
  if (element.value == 0)
    alert(1);
  else
    alert(2);
})

Kategoria: javascript

2 komentarzy grudzień 18th, 2008

Następny wpis


Kategorie

Linki

Tag Cloud

RSS