PHP fóra: Builder | JakPsatWeb | Webtrh
Nejste přihlášen(a)
Dobrý den,
mám v MySQL databázi tabulku categories, která
vypadá takto:
| id | name | position | parent |
|---|---|---|---|
| 1 | A | 1 | NULL |
| 2 | C | 3 | NULL |
| 3 | B | 2 | NULL |
| 4 | První A | 1 | 1 |
| 5 | První B | 1 | 3 |
| 6 | Druhá A | 2 | 1 |
| 7 | Třetí B | 3 | 3 |
| 8 | Druhá B | 2 | 3 |
| 9 | I | 1 | 4 |
| 10 | II | 2 | 4 |
| 11 | III | 3 | 4 |
A potřebuji z ní udělat menu, seřazené podle sloupce position:
A úplně nejlepší by bylo, kdybych měl pohled (view) menu,
který by vypadal takto:
| id | name | depth |
|---|---|---|
| 1 | A | 0 |
| 4 | První A | 1 |
| 9 | I | 2 |
| 10 | II | 2 |
| 11 | III | 2 |
| 6 | Druhá A | 1 |
| 3 | B | 0 |
| 5 | První B | 1 |
| 8 | Druhá B | 1 |
| 7 | Třetí B | 1 |
| 2 | C | 0 |
Asi by bylo vhodnejsi zvolit jinou strukturu pro vychozi tabulku.
Doporucuji procist nasledujici odkazyk
já bych řekl že tohle není špatná struktura. vytaháš si to rekurzivně (tj. pro každej uzel zavoláš dotaz). výsledek uložíš do cache (abys to netahal při každým dotazu), kterou budeš mazat jen při změně menu.
Odskoušeno a funkční oproti munulé verzi co jsem to smazal :D
sice jsem si už zvyk na dibi , ale něco jsem tu napsal :D
fetchMenu() funkce vytahá z mysql menu , array( parent, childern )
2. jej vypíše
function fetchMenu($parent = null){
$menu = array();
$q = mysql_query("select * from categories where parent='".$parent."' order by position")or die(mysql_error());
while($f = mysql_fetch_array($q)){
$menu[$f['id']] = array($f,fetchMenu($f['id']));
}
return $menu;
}
function echoMenu(array $menu,$sub=0){
$priority = array();
foreach($menu as $v){
echo str_repeat('-',$sub).$v[0]['name']."<br>";
echoMenu($v[1],$sub+1);
}
}
echoMenu(fetchMenu());
Editoval sodae (26. 4. 2009 12:14)
Nette Jabber Room – nette@conf.netlab.cz , všichni jste vítání
Twitter: http://twitter.com/MartinSadovy
sodae napsal(a):
function fetchMenu($parent = null){ $menu = array(); $q = mysql_query("select * from categories where parent='".$parent."' order by position")or die(mysql_error()); while($f = mysql_fetch_array($q)){ $menu[$f['id']] = array($f,fetchMenu($f['id'])); } return $menu; }
A nemůže se takový kód stát obrovským požíračem výkonu? Jen pro to ukázkové menu nahoře by se provedlo 12 dotazů do databáze (provede se vždy o jeden dotaz víc, než kolik položek menu má). Leda použít keš, s ní by to nemuselo vadit (pokud struktura nebude často aktualizována).
Nebylo by lepší si hned na začátku vytáhnout celou strukturu do pole a pracovat pak s tím? Případně celou práci nechat na databázi…?
Saying that Java is nice because it works on all OS's is like saying that anal sex is nice because it works on all genders.
MySQL nema moc podporu pro strom. Oracle tusim neco ma (dokaze spocitat deep).
Pokud chcete jedinim dotazem nacist strom z DB tak optimalni jsou ty metody co jsem odkazoval. Nevyhoda je pouze slozitejsi manipulace se stromem pri upravach, vkladani a vymazavani, ale selecty jsou relativne jednoduche.
to mutphy1: Když se budeš snažit načítat podkategorie po jedné v cyklu jak to píše sodae, tak rychle zjistíš, že tudy cesta nevede. Zbytečně zatěžuješ DB stroj. Pokud pak navrhneš robustnější aplikaci, kterou bude navštěvovat hodně lidí, tak zjistíš, že ti začne server padat na hubu.
Cesta je pouze pole např. http://www.quickpipe.com/…-menu-in-php (níže je uvedena složitější varianta, která je 100% funkční)
Jinak souhlasím s phx. Struktura DB by měla mít podobu http://dev.mysql.com/…al-data.html Je to geniálně jednoduché a přitom velmi rychlé. Pokud budeš dělat shop, tak se velmi rychle dá zjistit aktuální pozice, případně velmi rychle se dají vygenerovat cesty, mapy apod.