Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: optymalne rozwiazanie - drzewka
Forum PHP.pl > Forum > PHP
rzseattle
Ostatnio zastanawialem sie nad optymalnem rozwiazaniem dla wyswietlania drzewka. Mam w bazie tabele z grupami ktora poziada kolumne parent_id. Dzieki temu moge dowolnie zagniezdzac gurpy jedne w drugich (najwyzej stoja te z parent_id = 0) .

Teraz pobieram sobie to wszystko z bazy i zastanawiam sie w jaki sposob zformatowac tablice z wynikami aby smarty bez problemu (czytaj duzej ilosci kodu) mi ja wyswielil. Do tej pory mialem cos takiego
Kod
grupa nadrzedna |

                |

                -dzieci |

                        |

                        -dziecko 1 |

                        |          |

                        |          - dzieci...

                        |

                        -dziecko 2 |

                                   |

                                   - dzieci...

No ale taka tablica jest dosyc niewygoda w uzyciu. Chcialem ja miec bardziej plaska. Myslalem nad tym zeby wstawiac ilosc dzieci i tworzyc cos w rodzaju stosu.
Nadzedna -> 4 dzieci -> umiesc na stosie 4 -> dziecko -> ilosc swoich dzieci 2 -> umiesc na stosie 2 ->wyswietlone dwoje dzieci -> zdejmi ze stosu 2 -> dekrementuj zmienna najwyzej na stosie i lec dalej.

Ale jak pewnie zauwazlyliscie to jest niezle kombinactwo winksmiley.jpg , a jak znam zycie to istnieje pewnie jakis banalny sposob. No i wlasnie chcialbym spytc czy ktos takowego nie zna smile.gif ?
orson
witam ...

a moze w tablicy w bazie dodaj kolumne level i w niej stosuj cos takiego: [jako decimal !!! - wtedy dziala najlepiej bo masz sortowanie w czasie pobierania wynikow]
<n>.<n1><n2><n3>
czyli np:
0.000 - zerowa pozycja
1.000 - 1 pozycja
2.000 - 2 pozycja
2.100 - 2a
2.200 - 2b
2.210 - 2b-1 i tak dalej ... jezeli 10 pozycji na poziom to za malo to mozna zwiekszyc i zapisywac kazdy level na 2 cyfrach ...
w taki sposob masz bardzo ulatwione pobieranie rekordow ... nie musza byc po kolei bo dajesz order po level i mysql uklada sam i/lub wybiera pozycje do wyswietlenia [to sa liczby wiec jest duze pole do popisu] ... z wyswietlaniem tez nie ma problemu bo dajesz prostego ifa ze sprawdzaniem i robisz wciecia/podswietlenia itp ...

ja stosuje ta metode od jakiegos czasu i jest naprawde wygodna ...

cya
rzseattle
@orson

Twoje rozwiazanie jest ok, tylko ze :
a) po co mam wpowadzac nowa kolumne z danymi skoro z juz istniejacej moge ustalic strukture
cool.gif w moim przypadku rozwiazanie to wiecej komplikuje niz upraszcza, ja poprostu chcialem zoptymalizowac funkcje tworzaca drzewko , a stosujac levele musialbym przerobic funkcje tworzace grupe , tabele w bazie i dopiero na koncu funkcje tworzaca drzewko.

Ale wielkim plusem jest to ze baza juz wyrzuca odpowiedni wynik, jednak z ww powodow odpada.
rant
Witam

to może ja wtrące swoje trzy grosze winksmiley.jpg

proponuje przejrzeć ten bardzo ciekawy tekst jeśli chodzi o drzewa http://www.depesz.pl/various-sqltrees.php i http://www.depesz.pl/various-sqltrees-impl...lementation.php
może znajdziesz coś ciekawego dla siebie winksmiley.jpg)


pozdr
luzik
w mojej bazie jest tak.. id_kat|nazwa_kat|ojc_kat|
teraz po wczytaniu tabeli do tablicy robie tak.
[php:1:01eb150073]<?php
function petelka($ojciec='0'){
global $drzewo, $synowie, $glebokosc;
$glebokosc++;
foreach ($synowie[$ojciec] as $key => $syn) {
$nowy_ojciec=$syn;
$drzewo[]=array($syn, $glebokosc);
if(!empty($synowie[$nowy_ojciec])){
$this->petelka($nowy_ojciec);
$glebokosc--;
}
}
}

function rekurencja(){
global $synowie, $drzewo, $glebokosc;
$synowie='';
$drzewo='';
$glebokosc='';
$all = new all("dbconnect");
$all->dbconnect();
$katalogi = $all->db->getAssoc('SELECT id_kat, ojc_kat, nazwa_kat FROM kat ORDER BY ojc_kat, poz_kat');
foreach ($katalogi as $id_kat => $ojciec) {
$ojcowie[0]='';
if(!in_array($ojciec[0], $ojcowie)){
$g=0;
$ojcowie[$i]=$ojciec[0];
$i++;
}
$synowie[$ojciec[0]][]=$id_kat;
}
$this->petelka();
$roottree=array('0', '0');
array_unshift($drzewo, $roottree);
$katalogi['0']=array('null', 'Kategorie');
foreach($drzewo as $id){
$naz_drzewo[]=str_repeat("&nbsp ",$id[1]).$katalogi[$id[0]][1];
}
$this->drzewo=$drzewo;
$this->naz_drzewo=$naz_drzewo;
}
?>[/php:1:01eb150073]

to jest przyklad typowej rekurencji ...bez ograniczen na glebokosc
rzseattle
Cytat
Witam

to może ja wtrące swoje trzy grosze winksmiley.jpg

proponuje przejrzeć ten bardzo ciekawy tekst jeśli chodzi o drzewa http://www.depesz.pl/various-sqltrees.php i http://www.depesz.pl/various-sqltrees-impl...lementation.php
może znajdziesz coś ciekawego dla siebie winksmiley.jpg)

pozdr


Co prawda nie do konca mi chodzilo jak zorganizowac dane w bazie - ale te artykuly napewno mi sie przydadza. Okazalo sie ze uzywam 2 metody w 5 stopniowej skali optymalizacji laugh.gif . W kazdym razie pelne drzewka u mnie generowane sa u mnie tylko na potrzeby panelu admina wiec mniej mi zalezy na wydajnosci a bardziej na porzadku w bazie. Moge sobie pozwolic na jedno zapytanie na kazdy level, wiecz pobraniem danych nie ma problemu.

A dokladnie mi chodzilo o zformatowanie samej tablicy w php. Mam tablice i mam ja przekazac do SMARTY. I wlasnie sie zastanawialem jak to zrobic aby moj szablon nie byl full wypasiony i w sposob przejzysty wyswietlal drzewko.

@luzik

hmm u ciebie to sie wydaje spoko ale na sztywno wciskasz spacje w nazwe kategorii, podczas gdy to szablon powinien to robic. Ale twoj sposob (chyba bo jeszcze do siebie nie przenioslem) porzadkuje strukture - a to juz cos winksmiley.jpg. Tylko takie pytanie - czemu funkcje nazwales rekurencja ? Nie widze nigdzie zeby sama sieie wywolywala smile.gif.

Hmm jednak drzewka to nie jest taki banal jak by sie wydawalo, chyba dzisiaj poziedze i pomysle jak to SMATEMU przekazac zeby czulsie z tym dobrze laugh.gif
cagrET
Ze Smarty są same problemy. Proponuję zmienić język szablonów na taki który opiera się na natywnym php.
rzseattle
Cytat
Ze Smarty są same problemy. Proponuję zmienić język szablonów na taki który opiera się na natywnym php.

Prawde mowiac po raz pierwszy mam problem ze smarty i to tez tylko dlatego ze chcialbym wszystko w ramach znaczkow {} zrobic. W ostatecznosci zawsze moge sobie zadeklarwac odpowiednia funkcje w samym szablonie, ktora zrobi z tym wszystkim porzadek. Jak narazie poprostu chcialem to zrobic optymalnie. No ale jak widze chyba jednak bede musial w samym szablonie porzadnie pomajstrowac. Ehh nie lubie robic szablonow takich ze potem grafik przysyla mi maila "O co w tym chodzi?". Przeciez po to sa szablony aby takich sytuacji uniknac.
cagrET
W szablonie który używa natywnego php mozna pisać równie przejrzysty kod jak w Smarty. Wystarczy trochę samodyscypliny. Smarty po prostu nie pozwala ci na pewne rzeczy, więc ich nie robisz, a uzywając php leniwy koder żeby oszczędzić sobie pracy wstawia do szablonu kawalki kodu, które powinny się znaleźć w kodzie biznesowym aplikacji. I tak powstaje chaos biggrin.gif
rzseattle
Cytat
W szablonie który używa natywnego php mozna pisać równie przejrzysty kod jak w Smarty. Wystarczy trochę samodyscypliny. Smarty po prostu nie pozwala ci na pewne rzeczy, więc ich nie robisz, a uzywając php leniwy koder żeby oszczędzić sobie pracy wstawia do szablonu kawalki kodu, które powinny się znaleźć w kodzie biznesowym aplikacji. I tak powstaje chaos biggrin.gif


Maly OT wyszedl.
Musze sie z toba niezgodzic. Praktycznie nigdy nie wstawiam kodu php do szablonu. Jesli nawet tak sie zdarzy w raz na tysiac przypadkow to jest to kod ktoryobrabia dostarczone dane, czyli w rzeczywistosci nie powinien sie znajdowac w czesci biznesowej aplikacji. Granica zostaje zachowana w pelni, nawet jesli w szablonie jest duzo kodu o ile ten kod sam nie pobiera, tworzy, edytuje dostarczonych danych.
seaquest
a to moj sposob

[php:1:6e6206eb3c]<?php
function getsub($sid) {
global $db, $content;
$sql = "SELECT `id`,`name`,`type` FROM `categories` WHERE `sub`='{$sid}'";
$result = $db->Execute($sql);
while(!$result->EOF) {
$id = $result->fields['id'];
$name = $result->fields['name'];
$type = $result->fields['type'];
$result->MoveNext();
}
return $content;
}

?>[/php:1:6e6206eb3c]

wybaczcie, ze kod na AdoDB, ale....

a ten parametr $sid to id starszej kategorii, funkcja wyciaga wszystkie podkategorie i ich podkategorie itd

uwaga, bo czasami moze sie dlugo wykonywac ;-)
cagrET
rzseattle: nie rozumiem jak twój post ma się do mojej wcześniejszej wypowiedzi. Pisałem o czymś innym. Proponuję zapoznać się na przykład z http://phpsavant.com/ jak chcesz mieć zoptymalizowany kod.
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.