In mijn CMS'je gebruik ik twee recursieve functies om de volgende tabel in een net menuutje te zetten:

In dit voorbeeld heb ik "Overzicht" (nid=97) aangeklikt. Wat gebeurt er? De eerste functie bepaalt het pad van nid=97 naar de top (dus: 97 - 95 - 1 - 0) en de tweede loopt terug langs alle menu items om de boom te tekenen:

Dit alles kost mij in dit geval 7 queries. Omdat ik mijn systeem zo efficient mogelijk wil hebben, probeer ik nu een stukje code te schrijven dat alle menu items in 1 query selecteert en in een array stopt, waarna ik op de server middels een recursieve functie de boom teken:
De output van al dit moois is bijna goed, op 1 puntje na: de nodes zijn niet gesorteerd op "weight" en ik weet ook niet hoe ik dat moet doen:

Ik heb gezocht op php.net, maar de functie asort laat de gebruiker geen property definieren waarop je kunt sorteren. Bovendien, waar moet ik deze dan in mijn functie aanroepen? Genoeg vragen dus. Ik hoop dat jullie mij op weg kunnen helpen. Voor de duidelijkheid: het menuutje moet er dus uitzien zoals in het eerste plaatje
Als de functie uiteindelijk werkt ga ik kijken wat sneller is, en wat de winst is. De boom zal redelijkerwijs nooit meer dan 1000 nodes bevatten. Vraag me af of MySQL snel 1000 nodes geselecteerd krijgt...ook graag hierover jullie ervaringen...

In dit voorbeeld heb ik "Overzicht" (nid=97) aangeklikt. Wat gebeurt er? De eerste functie bepaalt het pad van nid=97 naar de top (dus: 97 - 95 - 1 - 0) en de tweede loopt terug langs alle menu items om de boom te tekenen:

Dit alles kost mij in dit geval 7 queries. Omdat ik mijn systeem zo efficient mogelijk wil hebben, probeer ik nu een stukje code te schrijven dat alle menu items in 1 query selecteert en in een array stopt, waarna ik op de server middels een recursieve functie de boom teken:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
| $result = db_query("SELECT * FROM nodes"); for ($i = 0; $i < db_num_rows($result); $i++) { $node = db_fetch_array($result); $navitems[$node['nid']] = Array('pid'=>$node['pid'], 'title'=>$node['title'], 'alias'=>$node['alias'], 'weight'=>$node['weight']); } function buildMenu($menuItems, $activeItem, $curItem=0, $depth = 0) { $unfoldItems = array($activeItem); while ($unfoldItems[count($unfoldItems)-1] != 0) $unfoldItems[] = $menuItems[$unfoldItems[count($unfoldItems)-1]]['pid']; $first = true; foreach ($menuItems as $itemKey=>$item) { if ($item['pid'] == $curItem) { if ($first) { if ($depth > 0) echo '<tr><td> </td><td>'; echo '<table border="1">'; $first = false; } echo '<tr><td>></td>'; if ($activeItem == $itemKey) echo '<td>'.$item['title'].'</td></tr>'; else echo '<td><a href="'.$item['alias'].'">'.$item['title'].'</a></td></tr>'; if (in_array($itemKey, $unfoldItems)) buildMenu($menuItems, $activeItem, $itemKey, $depth + 1 ); } } if (!$first) { echo '</table>'; if ($depth > 0) echo '</td></tr>'; } } buildMenu($navitems, 97); |
De output van al dit moois is bijna goed, op 1 puntje na: de nodes zijn niet gesorteerd op "weight" en ik weet ook niet hoe ik dat moet doen:

Ik heb gezocht op php.net, maar de functie asort laat de gebruiker geen property definieren waarop je kunt sorteren. Bovendien, waar moet ik deze dan in mijn functie aanroepen? Genoeg vragen dus. Ik hoop dat jullie mij op weg kunnen helpen. Voor de duidelijkheid: het menuutje moet er dus uitzien zoals in het eerste plaatje
Als de functie uiteindelijk werkt ga ik kijken wat sneller is, en wat de winst is. De boom zal redelijkerwijs nooit meer dan 1000 nodes bevatten. Vraag me af of MySQL snel 1000 nodes geselecteerd krijgt...ook graag hierover jullie ervaringen...
"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."