Hallo!
Ich versuche mich erstmals an OOP unter PHP und habe ein Problem mit dem Handling von Arrays als Rückgabetyp einer Methode. Mein Problem beschreibe ich zu erst, der Quellcode steht weiter unten.
Mein Ziel ist es, eine Klasse "Menu" zu bauen, die in einem Array $eintraege "Menu_eintrag"-Objekte speichern kann, wobei jedes "Menu_eintrag"-Objekt auch wieder weitere "Menu_eintrag"-Objekte in einem Array $untermenu_eintraege speichern kann. Jedes "Menu_eintrag"-Objekt enthält eine Variable $seite_id zur Identifikation. Die Daten für die zu erzeugenden Objekte kommen aus einer DB (deren Umsetzung in eine OOP-Variante später kommt) und enthalten neben der seite_id und diversen Inhalten auch einen sog. "parent"-Wert, der angibt, wo sich das entsprechende Objekt in der Hierarchie zu befinden hat.
Kurzes Beispiel:
Objekt1 mit seite_id = 1 und parent = 0;
Objekt2 mit seite_id = 2 und parent = 1;
Objekt3 mit seite_id = 4 und parent = 1;
Objekt4 mit seite_id = 7 und parent = 2;
Objekt1 gehört zur "obersten" Ebene wegen parent = 0.
Objekt2 gehört zur Ebene 2 und ist im Baum unter Objekt1 angeordnet wegen parent = 1.
Objekt3 gehört zur Ebene 2 und ist im Baum unter Objekt1 angeordnet wegen parent = 1.
Objekt4 gehört zur Ebene 3 und ist im Baum unter Objekt2 angeordnet wegen parent = 2.
Objekte mit parent = 1 sind also "Kind" von Objekt1 und gehören damit zur zweiten Ebene und sollen in $untermenu_eintraege von Objekt1 gespeichert werden.
Objekt4 ist damit Kind von Objekt2 und sollten in dessen $untermenu_eintraege gespeichert werden.
So weit ist das hoffentlich noch verständlich.
Ich möchte nun alle "Menu_eintrag"-Objekte erzeugen, deren Daten (u.a. ID und parent) aus einer DB kommen. Dazu hole ich mir aus der DB zu erst alle Daten, deren parent = 0 ist (also oberste Ebene) und speicher diese im Array $eintraege des "Menu"-Objekts. Das klappt noch. (Zeile 12-26)
Nun hole ich mir sämtliche Daten, deren parent > 0 ist, also Einträge, die irgendwo unterhalb der ersten Ebene "einzuhängen" sind. Dazu möchte ich das Array $eintraege durchlaufen und für jedes Element überprüfen, ob dessen seite_id = dem parent-Wert des aktuellen Datensatzes aus der DB ist. Wenn dem so ist, soll er ein "Menu_eintrag"-Objekt erzeugen und dem entsprechenden Array des "Menu_eintrag"-Objekt der ersten Ebene hinzufügen. Das funktioniert auch noch. (Zeile 28-48)
Nun möchte ich aber auch gerne für sämtliche Einträge aus der DB der Ebenen 2 und höher Objekte erzeugen und sie den entsprechenden Eltern-Objekten zuweisen. (Im Idealfall soll das eine Klasse für vollständig generische Menüs werden.) Sinnvoll wäre es dabei ja, eine Methode "untermenu_eintraege_fuellen()" zu schreiben, die sich rekursiv immer wieder aufrufen kann und so bis zur entsprechenden "letzten" Ebene den Baum durchläuft und die Objekte entsprechend einhängt.
Nun meine eigentliches Problem (hier erst? :-): Ein Objekt der zweiten Ebene (z.B. Objekt2) kann ich folgendermaßen hinzufügen:
$this->menu_eintraege[0] = new Menu_eintrag(); // Objekt erzeugen und Objekt1 zuweisen
$this->menu_eintraege[0]->setSeite_id(2); // Objekt die seite_id = 2 geben.
Aber wie kann ich jetzt im Beispiel oben das Objekt4 erzeugen und Objekt2 hinzufügen? Mit
$this->menu_eintraege[0]->getUntermenu_eintraege();
bekomme ich das Array der Kinder, aber wie komme ich an ein bestimmtes Arrayelement heran, um einem der Kinder wieder ein Objekt zuordnen zu können?
Dieser Code funktioniert natürlich nicht:
$this->menu_eintraege[0]->getUntermenu_eintraege()[0] = new Menu_eintrag();
Um lesend auf das Objekt zugreifen zu können, kann ich einfach das Array durchlaufen und das entsprechende Element in einer Variablen speichern und dessen get-Methoden aufrufen, das ist kein Problem. Um aber Daten zu verändern, muss ich ja das "Original"-Objekt nehmen, weiß aber halt nicht, wie ich das mache.
In Java z.B. gibt es da meines Wissens mehrere Möglichkeiten, Collections zu durchlaufen, aber in PHP weiß ich (noch) nicht, wie das geht.
Vielen Dank für die Geduld und jegliche Hilfe!
Haefti
------------------------------
Quellcode:
class Menu_eintrag
{
var $inhalte;
var $untermenu_eintraege;
function Menu_eintrag()
{
$this->inhalte = array();
}
function addUntermenu_eintraege($object)
{
$this->untermenu_eintraege[count($this->untermenu_eintraege)] = $object;
}
function getUntermenu_eintraege()
{
return $this->untermenu_eintraege;
}
function setSeite_id($seite_id)
{
$this->inhalte[0] = $seite_id;
}
function getSeite_id()
{
return $this->inhalte[0];
}
1 class Menu
2 {
3 var $menu_eintraege; // Array mit Menu_eintrag-Objekten
4
5 function Menu()
6 {
7 $this->eintraege_fuellen();
8 }
9
10 function eintraege_fuellen()
11 {
12 $i = 0;
13 $query = "SELECT seite_id FROM seite WHERE parent = 0 ORDER BY sortierung;";
14 $result = mysql_query($query, $this->verbindung); // Abfrage machen
15 if (!$result)
16 {
17 print mysql_error();
18 die("Query $query ist ungültiges SQL.");
19 }
20 while ($data = mysql_fetch_array($result)) // Zeilenweise auslesen
21 {
22 $this->menu_eintraege[$i] = array();
23 $this->menu_eintraege[$i] = new Menu_eintrag();
24 $this->menu_eintraege[$i]->setSeite_id($data['seite_id']);
25 $i++;
26 }
27
28 $query = "SELECT seite_id, parent FROM seite WHERE parent > 0 ORDER BY parent, sortierung;";
29 $result = mysql_query($query, $this->verbindung); // Abfrage machen
30 if (!$result)
31 {
32 print mysql_error();
33 die("Query $query ist ungültiges SQL.");
34 }
35 while ($data = mysql_fetch_array($result)) // Zeilenweise auslesen
36 {
37 for ($i = 0; $i < count($this->menu_eintraege); $i++) // durchlaufe das Array der ersten Ebene
38 {
39 $menu_eintrag = $this->menu_eintraege[$i];
40 if ($data['parent'] == $this->menu_eintraege[$i]->getSeite_id()) // wenn der aktuelle parent gleich der Seiten_id
41 {
42 $temp_object = new Menu_eintrag();
43 $temp_object->setSeite_id($data['seite_id']);
44 $this->menu_eintraege[$i]->addUntermenu_eintraege($temp_object);
45 }
46
47 }
48 }
49 }
50 }