INSERT INTO `pages` VALUES(1, NULL, 'Velkommen', NULL); INSERT INTO `pages` VALUES(2, NULL, 'Lidt om mig selv', NULL); INSERT INTO `pages` VALUES(3, NULL, 'CV', NULL); INSERT INTO `pages` VALUES(4, NULL, 'Kontakt', NULL); INSERT INTO `pages` VALUES(5, 1, 'En underside til Velkommen', NULL); INSERT INTO `pages` VALUES(6, 3, '2001', NULL); INSERT INTO `pages` VALUES(7, 3, '2005', NULL); INSERT INTO `pages` VALUES(8, 3, '2008', NULL);
Og derefter en PHP som skriver siderne ud i træstruktur:
function print_pages($parent = NULL) { echo '<ul>'; if($parent == NULL) { $pages_query = mysql_query("SELECT * FROM pages WHERE parent IS NULL"); } else { $pages_query = mysql_query("SELECT * FROM pages WHERE parent = '$parent'"); } while($page = mysql_fetch_array($pages_query)) { echo '<li>'. $page['title'] .' | <a href="admin.php?delete='. $page['id'] .'">Delete</a></li>'; echo '<li>'. print_pages($page['id']) .'</li>'; } echo '</ul>'; }
print_pages();
Men den laver nogle gange nogen tomme <li></li> osv. Er der nogen som kan se om alt min kode osv. er optimalt, da jeg meget gerne vil have et solidt "fundament" inden jeg fortsætter.
Problemet er vel at du kalder print_pages uanset om der er nogle underpunkter eller ej, men du skriver alligevel en <ul> ud (og sådan en må ikke være tom - der skal være en <li> inde i den). Det er sandsynligvis derfor du oplever problemet
Lav din funktion om så du checker antallet af børn inden du skriver <ul></ul> ud (eller check inden du kalder dig selv igen - dit valg).
Om nested sets er overkill - det kommer jo an på hvordan man ser på det. Din nuværende struktur er sikkert hurtig nok et godt stykke ud i fremtiden - selvom menuer jo normalt er noget der skal genereres ret tit - men til gengæld kunne nested sets måske gøre din PHP-kode mere læsevenlig.
Dermed ikke sagt at nested sets altid er det jeg ville vælge, da det trods alt er en smule mere komplekst at forholde sig til. Tidligere på året skulle jeg lave en ASP.NET-baseret menu hvor det var fastlagt at vi kun havde overskrifter og menupunkter (dermed kun 2 niveauer - hovedniveauet og underniveauet, og det var kun underniveauet der var egentlige links). Samtidigt skulle vi ikke have nogle "fold ud/ind"-funktionalitet.
I den situation lavede jeg en tabelstruktur der lød id, text, link, parent, sortvalue, og bestemte at sortvalue ville køre på et globalt niveau, så en enkelt query med ORDER BY sortvalue ville hente hele menuen ud i den ønskede rækkefølge. I min kode kunne jeg så bestemme om det skulle formateres som en overskrift eller et menupunkt, ud fra om parent var NULL. Dertil kom et administrationsinterface, samt et par stored procedures til at foretage oprettelse, ændring af rækkefølge, samt sletning, så der ikke var huller i sortvalue.
Det var måske en lidt fusket måde at gøre det på, men det resulterede i meget læsevenlig kode. Tricket mister i høj grad sin værdi hvis man har flere niveauer end 2 (det vil enten kræve redundans i tabellen, eller queries til at beregne niveauet), men da det ikke var et problem, virkede det som det bedste valg i min situation :)
-> pidgeot - det er faktisk meget sjovt; jeg tænkte på at dét (nested sets) ville være en smart løsning, men har aldrig hørt om det før, det var bare måden jeg ville gøre det på. jeg havde så ikke lige tænkt på alle de lettere avancerede ting der kommer senere i artiklen du linker til, men selve tabel-strukturen var lige efter mit hovede :)
jeg havde bare lidt svært ved at forklare det, hvorfor ved jeg ikke, da det ser rimelig simpelt ud når jeg læser denne artikel :)
Husk at mysql_query kun kan klare et statement af gangen. Du bliver nødt til enten at lave en stored procedure eller dele op med flere kald til mysql_query - eller gå over til mysqli, hvilket også giver dig mulighed for parameteriserede queries.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.