Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Dodawanie danych do tablicy rekursywnej
Forum PHP.pl > Forum > PHP
Sztef89
Witam, próbuje zrobić wyświetlanie komentarzy z opcją rodzic/dziecko czyli komentarz i odpowiedzi do nich. Google podpowiada że trzeba użyć tablic rekursywnych aby wygenerować drzewo komentarzy. Niestety z takimi tablicami nie miałem okazji się bawić do tej pory.

Mam taką tablicę:

  1. $dane = array ( "14" => array ("ID" => "14", "PARENT" => "0", "18" => array ("ID" => "18", "PARENT" => "14"),"19" => array ("ID" => "19", "PARENT" => "14")), "24" => array ("ID" => "14", "PARENT" => "0"));
  2.  
  3. print_r($dane);


  1. Array
  2. (
  3. [14] => Array
  4. (
  5. [ID] => 14
  6. [PARENT] => 0
  7. [18] => Array
  8. (
  9. [ID] => 18
  10. [PARENT] => 14
  11. )
  12.  
  13. [19] => Array
  14. (
  15. [ID] => 19
  16. [PARENT] => 14
  17. )
  18.  
  19. )
  20.  
  21. [24] => Array
  22. (
  23. [ID] => 14
  24. [PARENT] => 0
  25. )
  26.  
  27. )


Chciałbym dołączać dane do tej tablicy w pętli while po pobraniu danych z bazy.

I teraz pojawia się pytanie: Jak dodać np. do 24 kolejne dziecko ? Albo jak dodać do 19 dziecko ?
marins
proponuje Ci zrobić to na obiektach:

  1. class komentarz {
  2.  
  3. //tutaj trzymasz tylko komentarze z PID 0
  4. static $mainArray = array();
  5.  
  6. //tutaj trzymasz wszystkie obiekty na zasadzie ID => obiekt komentarz
  7. static $idToObject = array();
  8.  
  9. //lista dzieci dla tego elementu
  10. private $childrens = array();
  11.  
  12. public function __construct($id,$parent_id,$tresc) {
  13. //przypisujesz wszyskie parametry
  14.  
  15. //dodajesz ten obiekt do $idToObject z kluczem jako id i obiektem
  16. self::$idToObject[$id] = $this;
  17.  
  18. if ( $parent_id == 0 ) {
  19. self::$mainArray[] = $this;
  20. }
  21. }
  22.  
  23.  
  24. public function addchildren(komentarz $object) {
  25. $this->childrens[] = $object;
  26. }
  27.  
  28. //generujesz html dla pojedynczego komentarza
  29. public function print() {
  30.  
  31. }
  32.  
  33. public function getChildrens() {
  34. return $this->childrens;
  35. }
  36. }


aby wyswietlic wszystkie komentarze z PARENT = 0 - robisz petle po

komentarz::$mainArray
Sztef89
Dzięki za odpowiedź. W trakcie czekania na ta odpowiedź wpadłem na o wiele "lżejszy" pomysł smile.gif

Wyświetlanie komentarzy w formie drzewa = odpowiednio duże marginesy z lewej strony to tylko estetyka, aby użytkownik wiedział do którego komentarza to odpowiedzi. Jako, że robienie struktury na drzewie a potem wyświetlanie to dość spore obciążenie dla serwera (aby zachować strukturę musimy wczytać wszystkie komentarze), postanowiłem wymyślić coś lepszego.

W strukturze tabeli z komentarzami mamy takie kolumny:
ID (zwiększane AI), KEY, DEPH
I to nam wystarczy ! Teraz gdy dodajemy zwykły komentarz ustawiamy tą samą wartość w KEY co w kolumnie ID, a gdy komentarz jest odpowiedzią do innego to pobieramy jego ID i ustawiamy w KEY i zwiększamy DEPH o jeden smile.gif

Wyświetlając sortujemy wyniki po KEY oraz ewentualnie dacie dodania wpisu i dodajemy odpowiednie marginesy w zależności od wartości DEPH. Możemy wprowadzić paginację bo jak widzicie nie musimy tworzyć żadnej struktury smile.gif


Na razie szukam sposobu jak ustawić tą samą wartość w polu KEY co w polu ID w trakcie dodawania wpisu. Takie coś niestety nie działa:
INSERT INTO `komentarz` (`key`, `deph`) VALUES (AUTO_ICREMENT, 5)

Można by przed zapisem wysłać zapytanie do bazy jaka jest aktualnie największa wartość kolumny ID, zwiększyć ją o jeden i dopiero wywołać inserta ale ja wolałbym zrobić to na jednym zapytaniu, o ile jest taka możliwość smile.gif Czy wiecie jak to zrobić ?
marins
Albo przejmij po dodaniu wpisu `insert id` i zrob update

pamietaj by ograniczyc depth w html - bo przy levelu 100 będziesz miał np.: -20px * 100 = -2000px biggrin.gif

odobiście jestem przeciwny takim drzewkom komentarzy - ale kto co lubi biggrin.gif
Sztef89
Nom ale to nadal 2 zapytania. Czyli się nie da odczytać wartość AI tej kolumny podczas robienia INSERTa ?
Oczywiście założyłem w algorytmie wyświetlającym ze jak przekroczy ileś tam to nie robi już większego marginesu smile.gif

Jestem nowy w tym temacie, na razie w moim pomyślę nie widzę żadnych wad. Mógłbyś napisać coś więcej dlaczego jesteś przeciwny takim drzewom ?


Udało mi się zrobić to na jednym zapytaniu:
  1. INSERT INTO `komentarz` (`key`, `deph`, `tresc`) SELECT MAX(id)+1, 0, '$tresc' FROM komentarz


--
Robię system komentarzy do pracy inżynierskiej. Za jakieś dwa dni skończę i będziecie mogli zobaczyć jak działa smile.gif Jak będą chętni to zamieszczę linka aby zobaczyć jak powyższe rozwiązania działają w praktyce smile.gif
marins
Cytat(Sztef89 @ 11.12.2011, 15:26:51 ) *
Mógłbyś napisać coś więcej dlaczego jesteś przeciwny takim drzewom ?

Wówczasz dla mnie całość jest nieczytelna - nie lubię jak mi coś lata prawo lewo. Łatwo zgubić wątek - rozwiązanie ze zwykłą listą jest przejrzyste (wizualnie).
Nie widzę sensu wątkowania - to nie forum biggrin.gif

Sztef89
Cytat(marins @ 11.12.2011, 22:32:24 ) *
Wówczasz dla mnie całość jest nieczytelna - nie lubię jak mi coś lata prawo lewo. Łatwo zgubić wątek - rozwiązanie ze zwykłą listą jest przejrzyste (wizualnie).
Nie widzę sensu wątkowania - to nie forum biggrin.gif


Ahaaa, Ty jesteś przeciwko robienia marginesów dla odpowiedzi, a nie przeciw rozwiązaniu jak dopasowuje odpowiedzi do "rodziców", dobrze zrozumiałem ? smile.gif Moim zdaniem dodanie niewielkiego marginesu bardzo pomaga w orientacji gdy się czyta kilka dyskusji w komentarzach smile.gif Weźmy np.: bardzo dobry system komentarzy DISQUS, nie dość, że ma wcięcia to jeszcze możemy chować dyskusje, które nas nie interesują, moim zdaniem rozwiązania w DISQUS są genialne i bardzo dobrze się czyta komentarze. Mógłbym jedynie ponarzekać na ogromne marginesy do kolejnych odpowiedzi (aż 50px !). Jakby nie to, że ten system stoi na ich serwerze i nie da się postawić go na swoim serwerze, to że integracja z własną bazą użytkowników jest możliwa dopiero w wersji płatnej (w bardzo promocyjnej cenie 299$/miesiąc), to bym na pewno się zdecydował na ten system.
Ale widzę, że dobrze zrobiłem robiąc ten system samemu. Mam pewność, bynajmniej, że to będzie bardzo wydajnie chodziło.
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.