Ik verontschuldig mij bij voorbaat voor de lengte van mijn post. Laat eenieder zich daar echter niet door afschrikken, het zijn vooral plaatjes
Ik heb ze nodig om mijn probleem helder uiteen te kunnen zetten. Voor een meer ervaren PHP'er is de oplossing waarschijnlijk niet eens zo heel moeilijk? Enfin, mijn post:
Ik probeer al een aantal dagen een navigatiescript te maken, maar zit met enkele problemen, welke ook in de topics met zoekwoorden "recursive" en "tree" bijvoorbeeld niet naar voren komen. Ik zet ze hieronder zo goed mogelijk uiteen en hoop dat iemand mij een (stap in de richting van een) oplossing kan aandragen.
Ik heb de volgende MySQL tabel aangemaakt:
Ik denk dat dit voor zich spreekt. "Eten" is de parent in deze tree en heeft twee kinderen, "Groenten" en "Fruit". Op haar beurt heeft "Fruit" weer de kinderen "Apples", "Peren", etc.
De volledige boom is:
Nu probeer ik een script te maken wat zich gedraagt als de navigatie op, bijvoorbeeld http://www.ibm.com en http://www.nl.issworld.com. Deze werken als volgt (aan de hand van dit voorbeeld):
Zijnavigatie op Homepage:
Vervolgens klik ik bijvoorbeeld op "Fruit" en wordt dan naar http://www.mijnsite.com/index.php?node=2 gestuurd met de volgende zijnavigatie:
Als ik dan op "Appels" klik, wordt ik naar http://www.mijnsite.com/index.php?node=7 gerstuurd met de volgende zijnavigatie:
Klik ik vervolgens op "Elstar", dan ziet de zijnavigatie op http://www.mijnsite.com/index.php?node=11 er als volgt uit:
Twee live voorbeelden van bovenstaande situatie: http://www-1.ibm.com/indu...sp/event/scheduledevents/ en http://www.nl.issworld.com/view.asp?ID=142. Ik ga in de rest van mijn post uit van het voorbeeld bij IBM. In mijn geval zou "Fruit" bold zijn weergegeven (analoog aan Government bij IBM), Appels zou een lichtblauwe achtergrond hebben, Elsar zou een witte achtergrond hebben, en Peren, Bananen en Druiven een donkerblauwe achtergrond.
Bijvoorbeeld "Bananen" heeft geen kinderen, dus als ik naar http://www.mijnsite.com/index.php?node=9 ga, krijg ik de zijnavigatie:
Tot nu toe heb ik het volgende geschreven:
Voor bijvoorbeeld writenav(1) retourneert deze functie de volgende tabel in html:
Tot zover gaat alles goed. Wanneer ik in deze tabel op "Fruit" Klik, gaat ook alles nog naar wens -> writenav(3) retourneert:
Maar nu komt het probleem: als ik op bijvoorbeeld "Peren" klik, retourneert writenav(8):
In plaats van:
Hetzelfde gebeurt als ik op "Appels" klik. writenav(7) retourneert:
In plaats van
Als ik nu op "Elstar" zou klikken (writenav(11)), zou ik het volgende willen krijgen:
Mijn probleem is dus duidelijk. Ik wil met een en dezelfde functie, middels het aanroepen van alleen de waarde van de node wiens pagina de bezoeker oproept (index.php?node=waarde), een zich als hierboven beschreven tree laten schrijven.
Als we stellen dat:
level 1 = eten
level 2 = groenten, fruit
level 3 = spruitjes, witlof, spinazie, appels, peren, bananen, druiven
level 4 = elstar, granny smith
dan heb ik een routine nodig die kijkt tot welk level het de gevraagde node behoort. Als dat level 4 (bijvoorbeeld "elstar") is, moet writenav() uitzoeken tot welke parent deze node behoort ("appels") en dan de overige kinderen van die parent ("granny s") opzoeken. Vervolgens de overige nodes uit het level van die parent opzoeken ("peren", "bananen", "druiven") die tot dezelfde familie ("fruit") behoren en in de tabeloutput verwerken. Ik ga er vanuit dat de tree in principe oneindig diep kan worden. Als de tree dus meer levels dan vier heeft, bijvoorbeeld 6 (waarbij elstar wordt onderverdeeld in groene en rode en groene en rode beiden worden onderverdeeld in kleine en grote), dan blijft het principe heftzelfde. De html output van writenav zou dan ongeveer als volgt moeten zijn (aangenomen dat "kleine rode elstar is aangeklikt middels writenav(19) ofzo):
Ik breek er mijn hoofd nu al enkele dagen over, maak ga rond in cirkels. Ook zoeken op google heeft geen zin: ik heb tientallen artikelen gelezen en scripts bekeken, maar het heeft me niet op ideeen gebracht. Ik geef toe dat het gebruik van +, - en > niet erg consistent is. Als je een oneindig lange boom gaat uitklappen moet je goed nadenken over hoe je eea overzichtelijk houdt. Dat is echter voor de volgende stap. De reden dat ik puur html wil is dat er nog steeds bedrijven zijn die voor alle werknemers bepalen dat javascript uitstaat (in Duitsland vooral nog veel heb ik me laten vertellen). En daarbuiten: als het eenmaal werkt is het gewoon cool
Ik hoop dat er mensen zijn die mij verder kunnen helpen.
P.S. Voor als iemand het nodig heeft:
#
# Tabel structuur voor tabel `php_tree`
#
CREATE TABLE php_tree (
ident int(12) NOT NULL auto_increment,
uid int(12) NOT NULL default '0',
gui int(12) NOT NULL default '0',
parent int(12) NOT NULL default '-1',
haschild enum('0','1') NOT NULL default '0',
email varchar(80) default NULL,
UNIQUE KEY ident (ident),
KEY parent (parent)
) TYPE=ISAM PACK_KEYS=1;
#
# Gegevens worden uitgevoerd voor tabel `php_tree`
#
INSERT INTO php_tree VALUES (1, 1069541031, 999, 0, '1', 'Eten');
INSERT INTO php_tree VALUES (2, 1069541054, 999, 1, '1', 'Groenten');
INSERT INTO php_tree VALUES (3, 1069541079, 999, 1, '1', 'Fruit');
INSERT INTO php_tree VALUES (4, 1069541088, 999, 2, '0', 'Spruitjes');
INSERT INTO php_tree VALUES (5, 1069541108, 999, 2, '0', 'Witlof');
INSERT INTO php_tree VALUES (6, 1069541118, 999, 2, '0', 'Spinazie');
INSERT INTO php_tree VALUES (7, 1069541126, 999, 3, '1', 'Appels');
INSERT INTO php_tree VALUES (8, 1069541130, 999, 3, '0', 'Peren');
INSERT INTO php_tree VALUES (9, 1069541134, 999, 3, '0', 'Bananen');
INSERT INTO php_tree VALUES (10, 1069541137, 999, 3, '0', 'Druiven');
INSERT INTO php_tree VALUES (11, 1069546322, 999, 7, '0', 'elstar');
INSERT INTO php_tree VALUES (12, 1069546340, 999, 7, '0', 'granny smith');
De eigenlijke tabel bevat, zoals je ziet, wat meer gegevens dan hierboven beschreven. Met deze extra waarden gebeurt voorals nog niets. Ze zijn er voor om in de toekomst een zijnavigatie te kunnen maken aan de hand van iemand zijn inlog credentials
Ik probeer al een aantal dagen een navigatiescript te maken, maar zit met enkele problemen, welke ook in de topics met zoekwoorden "recursive" en "tree" bijvoorbeeld niet naar voren komen. Ik zet ze hieronder zo goed mogelijk uiteen en hoop dat iemand mij een (stap in de richting van een) oplossing kan aandragen.
Ik heb de volgende MySQL tabel aangemaakt:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| ------+--------+----------+-------------- ident | parent | haschild | email ------+--------+----------+-------------- 1 | 0 | 1 | Eten 2 | 1 | 1 | Groenten 3 | 1 | 1 | Fruit 4 | 2 | 0 | Spruitjes 5 | 2 | 0 | Witlof 6 | 2 | 0 | Spinazie 7 | 3 | 1 | Appels 8 | 3 | 0 | Peren 9 | 3 | 0 | Bananen 10 | 3 | 0 | Druiven 11 | 7 | 0 | Elstar 12 | 7 | 0 | Granny Smith ------+--------+----------+-------------- |
Ik denk dat dit voor zich spreekt. "Eten" is de parent in deze tree en heeft twee kinderen, "Groenten" en "Fruit". Op haar beurt heeft "Fruit" weer de kinderen "Apples", "Peren", etc.
De volledige boom is:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| Eten | +- Groenten | | | +-- Spruitjes | | | +-- Witlof | | | +-- Spinazie | | +-- Fruit | +-- Appels | | | +-- Elstar | | | +-- Granny Smith | +-- Peren | +-- Bananen | +-- Druiven |
Nu probeer ik een script te maken wat zich gedraagt als de navigatie op, bijvoorbeeld http://www.ibm.com en http://www.nl.issworld.com. Deze werken als volgt (aan de hand van dit voorbeeld):
Zijnavigatie op Homepage:
code:
1
2
3
| Eten + Groenten + Fruit |
Vervolgens klik ik bijvoorbeeld op "Fruit" en wordt dan naar http://www.mijnsite.com/index.php?node=2 gestuurd met de volgende zijnavigatie:
code:
1
2
3
4
5
| Fruit + Appels + Peren + Bananen + Druiven |
Als ik dan op "Appels" klik, wordt ik naar http://www.mijnsite.com/index.php?node=7 gerstuurd met de volgende zijnavigatie:
code:
1
2
3
4
5
6
7
| Fruit + Appels - Elstar - Granny Smith + Peren + Bananen + Druiven |
Klik ik vervolgens op "Elstar", dan ziet de zijnavigatie op http://www.mijnsite.com/index.php?node=11 er als volgt uit:
code:
1
2
3
4
5
6
7
| Fruit + Appels > Elstar - Granny Smith + Peren + Bananen + Druiven |
Twee live voorbeelden van bovenstaande situatie: http://www-1.ibm.com/indu...sp/event/scheduledevents/ en http://www.nl.issworld.com/view.asp?ID=142. Ik ga in de rest van mijn post uit van het voorbeeld bij IBM. In mijn geval zou "Fruit" bold zijn weergegeven (analoog aan Government bij IBM), Appels zou een lichtblauwe achtergrond hebben, Elsar zou een witte achtergrond hebben, en Peren, Bananen en Druiven een donkerblauwe achtergrond.
Bijvoorbeeld "Bananen" heeft geen kinderen, dus als ik naar http://www.mijnsite.com/index.php?node=9 ga, krijg ik de zijnavigatie:
code:
1
2
3
4
5
| Fruit + Appels + Peren - Bananen + Druiven |
Tot nu toe heb ik het volgende geschreven:
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
52
53
54
55
| function writenav($node) { $node = $_GET["node"]; $query = "SELECT * FROM php_tree WHERE (parent='$node' or ident='$node') ORDER BY ident, parent"; $result = mysql_query($query); $num_results = mysql_num_rows($result); echo "<!-- BEGIN: Display of branches -->\n"; echo "<table border=1>\n"; for ($i=0; $i<$num_results; $i++) { $row = mysql_fetch_array($result); echo " <tr>\n"; // Yes, children present if ($row["haschild"]=="1") { if ($node==$row["ident"]) { // Root of the tree echo '<td> </td>'; echo '<td>'.$row['email'].'</td>'; } else { // Leaf with children $link_node = $row["ident"]; echo '<td>+</td>'; echo '<td><a href="?node='.$row['ident'].'">'.$row['email'].'</a></td>'; } } else { // No, children not present if ($node!=$row["ident"]) { // Root of the tree without children echo '<td> </td>'; echo '<td><a href="?node='.$row['ident'].'">'.$row['email'].'</a></td>'; } else { // Leaf without children echo '<td>'.$row['email'].'</td>'; } } // Show database values ... echo '<td width=15>'.$row['haschild'].'</td>'; echo '<td width=15>'.$row['parent'].'</td>'; echo '<td width=15>'.$row['ident'].'</td>'; } echo "</table>"; } |
Voor bijvoorbeeld writenav(1) retourneert deze functie de volgende tabel in html:
HTML:
1
2
3
4
5
6
7
| ---+----------+---+---+--- | Eten | 1 | 0 | 1 ---+----------+---+---+--- + | Groenten | 1 | 1 | 2 ---+----------+---+---+--- + | Fruit | 1 | 1 | 3 ---+----------+---+---+--- |
Tot zover gaat alles goed. Wanneer ik in deze tabel op "Fruit" Klik, gaat ook alles nog naar wens -> writenav(3) retourneert:
HTML:
1
2
3
4
5
6
7
8
9
10
11
| ---+----------+---+---+--- | Fruit | 1 | 1 | 3 ---+----------+---+---+--- + | Appels | 1 | 3 | 7 ---+----------+---+---+--- + | Peren | 0 | 3 | 8 ---+----------+---+---+--- + | Bananen | 0 | 3 | 9 ---+----------+---+---+--- + | Druiven | 0 | 3 | 10 ---+----------+---+---+--- |
Maar nu komt het probleem: als ik op bijvoorbeeld "Peren" klik, retourneert writenav(8):
HTML:
1
2
3
| +----------+---+---+--- | Peren | 0 | 3 | 8 +----------+---+---+--- |
In plaats van:
HTML:
1
2
3
4
5
6
7
8
9
10
11
| ---+----------+---+---+--- | Fruit | 1 | 1 | 3 ---+----------+---+---+--- + | Appels | 1 | 3 | 7 ---+----------+---+---+--- > | Peren | 0 | 3 | 8 <--- "Peren" heeft een witte achtergrond (vgl. IBM) ---+----------+---+---+--- + | Bananen | 0 | 3 | 9 ---+----------+---+---+--- + | Druiven | 0 | 3 | 10 ---+----------+---+---+--- |
Hetzelfde gebeurt als ik op "Appels" klik. writenav(7) retourneert:
HTML:
1
2
3
4
5
6
7
| ---+--------------+---+---+--- | Appels | 1 | 3 | 7 ---+--------------+---+---+--- | Elstar | 0 | 7 | 11 ---+--------------+---+---+--- | Granny Smith | 0 | 7 | 12 ---+--------------+---+---+--- |
In plaats van
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| ---+--------------+---+---+--- | Fruit | 1 | 1 | 3 ---+------------------+---+--- + | Appels | 1 | 3 | 7 <-- "Appels" heeft een lichtblauwe achtergrond (vgl IBM) ---+------------------+---+--- - | Elstar | 0 | 7 | 11 <-- "Elstar" heeft een lichtblauwe achtergrond ---+--------------+---+---+--- - | Granny Smith | 0 | 7 | 12 <-- "Granny S" heeft een lichtblauwe achtergrond ---+--------------+---+---+--- + | Peren | 0 | 3 | 8 ---+--------------+---+---+--- + | Bananen | 0 | 3 | 9 ---+--------------+---+---+--- + | Druiven | 0 | 3 | 10 ---+--------------+---+---+--- |
Als ik nu op "Elstar" zou klikken (writenav(11)), zou ik het volgende willen krijgen:
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| ---+--------------+---+---+--- | Fruit | 1 | 1 | 3 ---+------------------+---+--- + | Appels | 1 | 3 | 7 <-- "Appels" heeft een lichtblauwe achtergrond (vgl IBM) ---+------------------+---+--- > | Elstar | 0 | 7 | 11 <-- "Elstar" heeft een witte achtergrond ---+--------------+---+---+--- - | Granny Smith | 0 | 7 | 12 <-- "Granny S" heeft een lichtblauwe achtergrond ---+--------------+---+---+--- + | Peren | 0 | 3 | 8 ---+--------------+---+---+--- + | Bananen | 0 | 3 | 9 ---+--------------+---+---+--- + | Druiven | 0 | 3 | 10 ---+--------------+---+---+--- |
Mijn probleem is dus duidelijk. Ik wil met een en dezelfde functie, middels het aanroepen van alleen de waarde van de node wiens pagina de bezoeker oproept (index.php?node=waarde), een zich als hierboven beschreven tree laten schrijven.
Als we stellen dat:
level 1 = eten
level 2 = groenten, fruit
level 3 = spruitjes, witlof, spinazie, appels, peren, bananen, druiven
level 4 = elstar, granny smith
dan heb ik een routine nodig die kijkt tot welk level het de gevraagde node behoort. Als dat level 4 (bijvoorbeeld "elstar") is, moet writenav() uitzoeken tot welke parent deze node behoort ("appels") en dan de overige kinderen van die parent ("granny s") opzoeken. Vervolgens de overige nodes uit het level van die parent opzoeken ("peren", "bananen", "druiven") die tot dezelfde familie ("fruit") behoren en in de tabeloutput verwerken. Ik ga er vanuit dat de tree in principe oneindig diep kan worden. Als de tree dus meer levels dan vier heeft, bijvoorbeeld 6 (waarbij elstar wordt onderverdeeld in groene en rode en groene en rode beiden worden onderverdeeld in kleine en grote), dan blijft het principe heftzelfde. De html output van writenav zou dan ongeveer als volgt moeten zijn (aangenomen dat "kleine rode elstar is aangeklikt middels writenav(19) ofzo):
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| ---+--------------+ | Fruit | ---+--------------- + | Appels | ---+--------------- - | Elstar | ---+---+----------+ | - | rode | ---+---+----------+ | > | grote | ---+---+----------+ | > | kleine | <-- geselecteerd ---+---+----------+ | - | groene | ---+---+----------+ - | Granny Smith | ---+--------------+ + | Peren | ---+--------------+ + | Bananen | ---+--------------+ + | Druiven | ---+--------------+ |
Ik breek er mijn hoofd nu al enkele dagen over, maak ga rond in cirkels. Ook zoeken op google heeft geen zin: ik heb tientallen artikelen gelezen en scripts bekeken, maar het heeft me niet op ideeen gebracht. Ik geef toe dat het gebruik van +, - en > niet erg consistent is. Als je een oneindig lange boom gaat uitklappen moet je goed nadenken over hoe je eea overzichtelijk houdt. Dat is echter voor de volgende stap. De reden dat ik puur html wil is dat er nog steeds bedrijven zijn die voor alle werknemers bepalen dat javascript uitstaat (in Duitsland vooral nog veel heb ik me laten vertellen). En daarbuiten: als het eenmaal werkt is het gewoon cool
Ik hoop dat er mensen zijn die mij verder kunnen helpen.
P.S. Voor als iemand het nodig heeft:
#
# Tabel structuur voor tabel `php_tree`
#
CREATE TABLE php_tree (
ident int(12) NOT NULL auto_increment,
uid int(12) NOT NULL default '0',
gui int(12) NOT NULL default '0',
parent int(12) NOT NULL default '-1',
haschild enum('0','1') NOT NULL default '0',
email varchar(80) default NULL,
UNIQUE KEY ident (ident),
KEY parent (parent)
) TYPE=ISAM PACK_KEYS=1;
#
# Gegevens worden uitgevoerd voor tabel `php_tree`
#
INSERT INTO php_tree VALUES (1, 1069541031, 999, 0, '1', 'Eten');
INSERT INTO php_tree VALUES (2, 1069541054, 999, 1, '1', 'Groenten');
INSERT INTO php_tree VALUES (3, 1069541079, 999, 1, '1', 'Fruit');
INSERT INTO php_tree VALUES (4, 1069541088, 999, 2, '0', 'Spruitjes');
INSERT INTO php_tree VALUES (5, 1069541108, 999, 2, '0', 'Witlof');
INSERT INTO php_tree VALUES (6, 1069541118, 999, 2, '0', 'Spinazie');
INSERT INTO php_tree VALUES (7, 1069541126, 999, 3, '1', 'Appels');
INSERT INTO php_tree VALUES (8, 1069541130, 999, 3, '0', 'Peren');
INSERT INTO php_tree VALUES (9, 1069541134, 999, 3, '0', 'Bananen');
INSERT INTO php_tree VALUES (10, 1069541137, 999, 3, '0', 'Druiven');
INSERT INTO php_tree VALUES (11, 1069546322, 999, 7, '0', 'elstar');
INSERT INTO php_tree VALUES (12, 1069546340, 999, 7, '0', 'granny smith');
De eigenlijke tabel bevat, zoals je ziet, wat meer gegevens dan hierboven beschreven. Met deze extra waarden gebeurt voorals nog niets. Ze zijn er voor om in de toekomst een zijnavigatie te kunnen maken aan de hand van iemand zijn inlog credentials
[ Voor 10% gewijzigd door Reveller op 28-11-2003 01:05 ]
"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."