Wir bauen heute ein Menusystem mit PHP und MySQL.
Von der Ausgabe her soll es so aussehen:
Code :
1 2 | Baum
Blume |
Code :
1 2 3 | Baum
Apfel
Blume |
PHP-Code:
<html>
<head>
<frameset cols="20%,80%">
<frame src="baum.php3" name="navi">
<frame src="haupt.php3" name="haupt">
</frameset>
</head>
<body>
Machen wir uns mal erst Gedanken über den Aufbau der Datenbank die das Menu steuern soll:
Code :
1 2 3 4 5 6 7 8 | # Table structure for table `menu`
CREATE TABLE menu (
mid int(11) NOT NULL auto_increment, = damit wir eine eindeutige Id haben über die alles gesteuert wird
eintrag char(25) NOT NULL default '', = das wird angezeigt im menu (z.b unser Baum)
vater int(11) NOT NULL default '0', = hier steht die vater id drin
href char(50) NOT NULL default '', = die seite wird aufgerufen
PRIMARY KEY (mid)
) TYPE=MyISAM; |
Code :
1 2 3 4 5 6 | # Dumping data for table `menu`
INSERT INTO menu VALUES (1, 'baum', 0, '');
INSERT INTO menu VALUES (2, 'blume', 0, '');
INSERT INTO menu VALUES (3, 'apfel', 1, 'apfel.htm');
INSERT INTO menu VALUES (4, 'boskop', 3, 'boskop.htm');
INSERT INTO menu VALUES (5, 'birne', 1, ''); |
Zum Vater muss ich noch etwas loswerden: wenn der Vater 0 ist, dann ist der Eintrag im Hauptmenu. Ansonsten steht die id vom übergeordneten Menu oder auch "Vatermenu" darin. Unser Apfel hat ja als Vorgänger(vater)id die id vom Baum. Oder andersrum: Alles was als vater die id 1 hat, wird aufgeklappt, wenn der Baum angeklickt wird.
Da wir ja im Menu immer das aktuell aufgeklappte Menu zeigen wollen, müssen wir ja die Information mitschleppen, was aufgeklappt ist.
Für diesen Zweck führe ich die Variable pos mit, die sich das ganze für mich merkt.
So, nach soviel Vorspann geht es jetzt los:
PHP-Code:
<?PHP
$link = mysql_pconnect("localhost","wwwrun");
$err = mysql_select_db("menusys",$link); # das sollte klar sein wir rufen unsere db an.
# und hier kommt der code kurz aber schwer zu verstehen ...
function baum($vater,$lpos) #vater welches menu wird gezeigt ; in lpos wird meine liste aufgebaut für den nächsten klick
{
global $link; # Der Link zur DB durch global auch in der Funktion bekannt.
global $wahl; # hier sind als Array die ids drin die aufgeklappt sind (kommt aus der var pos)
static $ebene = 0; # mit static erstelle ich eine Variable, die beim erneuten
# Aufruf der Funktion den Wert aus der Vorgängerfunktion behält.
# Die ist wichtig für die Rekursion. Der Startwert ist 0 und der
# wird hochgezählt beim Neuaufruf. Wenn ich also im Menu bei Apfel bin,
# ist der Wert bei 1.
$erg[$ebene] = mysql_query("SELECT * FROM `menu` WHERE `vater` = '$vater'",$link);
$menge = mysql_num_rows($erg[$ebene]);
# Das ist auch noch klar. Lese das aktuelle Menu aus der Datenbank aus und starte eine Schleife ...
for ($lo=0;$lo<$menge;$lo++) {
$row = mysql_fetch_row($erg[$ebene]); # Den Menu Eintrag auslesen, in $row[1]
# ist ja der menueintrag als text ..
$menu = "<a href=\"baum.php3?pos=".$lpos."|".$row[0]."\">".$row[1]."</a><br>";
# Hier bastel ich den Link zusammen. Am schwersten zu verstehen ist wohl
# pos=$lpos|$row[0], ich werde noch näher darauf eingehen.
if ($ebene > 0) { # Hier rücke ich einfach nur ein, je tiefer ich im Menu(Rekursion)
# bin, umso mehr Leerzeichen vorne dran
echo str_repeat("",$ebene);
}
echo $menu;
if ($row[0] == $wahl[$ebene+1]) { # Hier folgt der Aufruf der Funktion (ab in die Rekursion)
$ebene++; # ein Level hoch
baum($row[0],$lpos."|$row[0]");
$ebene--; # und wieder ein Level runter
}
}
}

Fangen wir doch mal mit pos=$lpos|$row[0] an. Wenn wir die Funktion zum erstenmal aufrufen, ist $lpos leer und $row[0] beim Menueintrag Baum = 1. Der Link sieht also so aus: baum.php3?pos=|1.
Jetzt klicken wir mal geistig den Link.
PHP-Code:
$wahl = explode("|",$_GET['pos']); # aus meiner pos mache ich ein array wahl - wahl[1] hat inhalt 1
baum(0,""); # starte die Funktion, liste alles auf was als vater 0 hat
$row[0] - id aus der datenbank ist 1
Ebene ist 0
damit ist $wahl[$ebene+1] = 1 weil ja das Array über die pos Variable entspechend gefüttert wurde.
Und somit rein in die if Abfrage:
Weil wir ja wieder die Funktion starten, zählen wir das Level von der Rekursion eins hoch (var ebene) der erste Wert ist ja unsere id - sprich 1 - bedeutet, alles was als Vater in der db die 1 hat, wird angezeigt und die neue $lpos im neuen Aufruf bekommt den wert "|1".
Der jetzt aufgeklappte Link vom Apfel ist so: baum?pos=|1|3
Die "|1" kommt von der Variable lpos "|3" aus der Datenbank und ist die id vom Apfel.
Hier ist die Variable wahl nach dem Anklicken so: wahl[1] = 1 und wahl[2] = 3.
Der index der Variable wahl spiegelt die Rekursionstiefe wieder und der Inhalt die aufzuzeigenen Menuids
(ich bitte um pm falls meine Erklärung zu unklar ist aber im Moment wüsste ich keine besserere Beschreibung).
Somit steht unser Menu.
Nur noch das angewähle im Hauptfenster des Framesets anzeigen:
PHP-Code:
<?php
if (sizeof($wahl) > 1) { # nur wenn wahl vorhanden ist
$id = $wahl[sizeof($wahl)-1]; # den letzten Eintrag von wahl ermitteln
# was anzuzeigen ist, aus db holen
$erg = mysql_query("SELECT `href` FROM `menu` WHERE `mid`='$id'",$link) or die(mysql_error());
$row = mysql_fetch_row($erg);
if ($row[0] != "") { # wenn ein Eintrag vorhanden ist, per javascript aufrufen
?>
<script language="JavaScript">
parent.haupt.location.href="<? echo $row[0]; ?>";
</script>
PAUSE Rekursion ist auch eine der schwersten Dinge bei der Programmierung. Falls einer eine bessere Erklärung hat: melden



Kommentar schreiben

Bereiche
Kategorien
Forum - Programming





Artikel bewerten