Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Tablica wielowymiarowa i obliczanie poziomu zagłębienia
Forum PHP.pl > Forum > PHP
adbacz
Chciałem sobie napisać skrypt, który rekurencyjnie będzie pobierał wszystkie rekordy z bazy i samodzielnie tworzył menu o zagłębieniu nieograniczonym. Wszystko działa jak powinno, lecz nie mogę obliczyć poprawnie zagłębienia. Tzn, chciałem dodać do kazdej tablicy pod indeksem lvl kolejna cyfrę, która odpowiadałaby zagłębieniu. Ale okazuje się, że dwa pierwsze zgłebienia zawsze maja taką samą cyfrę. Kolejne juz inkrementują normalnie, ale poza dwoma pierwszymi.

Tutaj jest funkcja:
  1. public function getAllSubs($id = 0, $lvl = 0) {
  2. $this->db->select('id, name, parent, delete_access');
  3. $this->db->where('parent', $id);
  4. $this->db->order_by('name', 'asc');
  5. $childs = array();
  6. $cats = array();
  7. $cats = $this->db->get('_calteb_category')->result_array();
  8. $count = count($cats);
  9. $lvl++; //Tutaj juz próbowałem wszystkiego. Instrukcji warunkowych, inkrementowania na końcu funkcji, nawet dodałem opcjonalny trzeci parametr razem z instrukcją warunkową, żeby za pierwszym razem nie inkrementował, ale to nic nie wychodziło jak powinno.
  10. if($count > 0) { $this->_count_all_subs += $count; } //Tutuaj obliczam ile jest dokładnie wszystkich rekordów, bo mogę sobie powiedzmy liczyć od jakiegoś danego poziomu/menu, podanego w parametrze $id funkcji.
  11. for($i=0; $i<$count; $i++) {
  12. $cats[$i]['lvl'] = $lvl;
  13. $childs = $this->getAllSubs($cats[$i]['id'], $cats[$i]['lvl']);
  14. if(count($childs) > 0) {
  15. for($j=0; $j<count($childs); $j++) {
  16. $childs[$j]['lvl'] = $lvl;
  17. $cats[$i][] = $childs[$j];
  18. }
  19. }
  20. }
  21. return $cats;
  22. }


A przykładowy wynik wygląda tak:
  1. [6] => Array
  2. (
  3. [id] => 13
  4. [name] => Kat-4ea3bef3d6eed
  5. [parent] => 0
  6. [delete_access] => 0
  7. [lvl] => 1
  8. [0] => Array
  9. (
  10. [id] => 17
  11. [name] => Kat-4ea3c2a04eb42
  12. [parent] => 13
  13. [delete_access] => 0
  14. [lvl] => 1
  15. [0] => Array
  16. (
  17. [id] => 19
  18. [name] => Kat-4ea3d061efaf0
  19. [parent] => 17
  20. [delete_access] => 0
  21. [lvl] => 2
  22. [0] => Array
  23. (
  24. [id] => 22
  25. [name] => Kat-4ea3d0ea39427
  26. [parent] => 19
  27. [delete_access] => 0
  28. [lvl] => 3
  29. [0] => Array
  30. (
  31. [id] => 53
  32. [name] => Kat-4ea3e8c36a927
  33. [parent] => 22
  34. [delete_access] => 0
  35. [lvl] => 4
  36. )
  37. )
  38. )
  39. )
  40. )


Mógłbym prosić o jakąś podpowiedź? Jestem świadomy tego, że popełniłem jakis błąd, ale od wczoraj nie mogę go znaleść.
nospor
  1. public function getAllSubs($id = 0, $lvl = 0) {
  2. //.......
  3. // $lvl++; TO WYWALASZ!
  4. //...
  5. $childs = $this->getAllSubs($cats[$i]['id'], $lvl+1); // I TU ZMIANA
  6. //......
  7. }


ps:
  1. if(count($childs) > 0) {
  2. for($j=0; $j<count($childs); $j++) {
  3. $childs[$j]['lvl'] = $lvl;
  4. $cats[$i][] = $childs[$j];
  5. }
  6. }

Y, czemu dzieciom przypisujesz poniżej ten sam level co rodzicowi?
adbacz
Ale wtopa;/ Dzięki, że zwróciłeś na to uwagę nospor.

  1. if(count($childs) > 0) {
  2. for($j=0; $j<count($childs); $j++) {
  3. $childs[$j]['lvl'] = $lvl + 1; //Wystarczyło dodac jeden ;/
  4. $cats[$i][] = $childs[$j];
  5. }
  6. }


Dziękuję.
nospor
Ale po co w ogole dzieciom ustawiasz lvl?
Przecieć level dziecka niejako załatwia ci ta linijka:
$cats[$i]['lvl'] = $lvl;
Przecież dzieci przez to przechodza.
adbacz
Fakt, masz rację. Teraz chciałbym pójść o krok dalej, i zamiast robić tablicę wielowymiarową, zrobić jednowymiarową, ale żeby zachować tą kolejność i poziom zagłębienia lvl.
Pilsener
Moim zdaniem źle to robisz, rezasz niepotrzebnie bazę a kod jest nieczytelny i skomplikowany.

1. Użyj jednego zapytania które zrzuci wszystko za jednym razem
2. Użyj tablic dwuwymiarowej, gdzie będzie tylko ID rodzica i ID elementu
3. Teraz mając taką tablicę należy użyć rekurencji, by ją wyświetlić

Tu masz więcej info:
http://blog.mwojcik.pl/2008/02/17/drzewa-k...-php-metoda-ip/
Sephirus
Po zagłębieniu się w temacie popieram @up
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.