Mik3e
Erfahrenes Mitglied
Hierarchie in Array packen (MPTT - Modified Preorder Tree Traversal Algorithmus)
Hi zusammen,
Grundlegendes:
Ich habe einen Hierarchiebaum (in diesem Beispiel einen mini-produktkatalog) nach den Regeln des "Modified Preorder Tree Traversal (MPTT)" Algorithmus in der Datenbank hinterlegt. (siehe auch http://www.sitepoint.com/print/hierarchical-data-database).
Alle in diesem Thread angesprochenen Werte beziehen sich auf die beigefügte Skizze!
Methode: getCategoryTree($startNode);
Nun bin ich gerade dabei mir eine Klasse zu schreiben, die mir unter anderem eine Methode "getCategoryTree($startNode)" bietet. Diese Methode soll (wie der Name schon verrät) den Hierarchiebaum unterhalb von $startNode in Form eines mehrdimensionalen Arrays aus der DB zurückliefern.
Returns: Array
Der Array der zurückgeliefert wird, soll folgendermaßen aussehen (auf der Skizze entspricht dies den grünen Zahlen rechts oberhalb der Elemente):
Das hat den Sinn, dass der Array jederzeit einfach (und vor allem schnell) mittels [phpf]foreach[/phpf] abgebildet werden kann.
Mein Problem:
Die Methode funktioniert bereits einwandfrei. Die Hierarchische Struktur wird einwandfrei durchlaufen und das Ergebnis wird mit den korrekten Einrückungen angezeigt.
ABER: Wie bekomme ich das nun in einen mehrdimensionalen Array? (Weil mit der Anzeige kann ich nicht viel anfangen). Ich kenne die Ebene auf der sich ein Element befindet (entspricht der Elementanzahl des $layerStack).
Vielleicht habt Ihr auch eine andere Lösung für den Aufbau des Arrays...
Hier die Methode für das Auslesen der Hierarchie:
Und hier das derzeitige Ergebnis:
Anlagen:
1. Das hier verwendete Beispiel als Diagramm zum leichteren Verständnis
2. Ein Snapshot der verwendeten Test-Tabelle "tbl_product_category"
Vielen Dank vorab für die Hilfe.. ich steh wahrscheinlich nach dem langen Arbeitstag im Moment nur total auf der Leitung
Ciao,
Mike
Hi zusammen,
Grundlegendes:
Ich habe einen Hierarchiebaum (in diesem Beispiel einen mini-produktkatalog) nach den Regeln des "Modified Preorder Tree Traversal (MPTT)" Algorithmus in der Datenbank hinterlegt. (siehe auch http://www.sitepoint.com/print/hierarchical-data-database).
Alle in diesem Thread angesprochenen Werte beziehen sich auf die beigefügte Skizze!
Methode: getCategoryTree($startNode);
Nun bin ich gerade dabei mir eine Klasse zu schreiben, die mir unter anderem eine Methode "getCategoryTree($startNode)" bietet. Diese Methode soll (wie der Name schon verrät) den Hierarchiebaum unterhalb von $startNode in Form eines mehrdimensionalen Arrays aus der DB zurückliefern.
Returns: Array
Der Array der zurückgeliefert wird, soll folgendermaßen aussehen (auf der Skizze entspricht dies den grünen Zahlen rechts oberhalb der Elemente):
Code:
$returnedArray[0]="Auto"
$returnedArray[0][0]="Opel"
$returnedArray[0][1]="Audi"
$returnedArray[1]="Motorrad"
$returnedArray[1][0]="Yamaha"
$returnedArray[1][0][0]="YZF R1"
$returnedArray[1][0][1]="Tomcat"
Mein Problem:
Die Methode funktioniert bereits einwandfrei. Die Hierarchische Struktur wird einwandfrei durchlaufen und das Ergebnis wird mit den korrekten Einrückungen angezeigt.
ABER: Wie bekomme ich das nun in einen mehrdimensionalen Array? (Weil mit der Anzeige kann ich nicht viel anfangen). Ich kenne die Ebene auf der sich ein Element befindet (entspricht der Elementanzahl des $layerStack).
Vielleicht habt Ihr auch eine andere Lösung für den Aufbau des Arrays...
Hier die Methode für das Auslesen der Hierarchie:
PHP:
// getCategoryTree: Liefert die gesamte hierarchische Struktur unter
// $startNode. Um das gesamte Verzeichnis zu listen, muss der
// ROOT-Node als $startNode übergeben werden.
//-------------------------------------------------------------------
function getCategoryTree($startNode) {
$startNodeLft=0;
$startNodeRgt=0;
// Hilfs-Stack zum bestimmen der Ebenen initialisieren
//-------------------------------------------------------------------
$layerStack=array(); // Hilfs-Stack zum bestimmen der Ebenen
// LEFT & RIGHT Order von $startNode einlesen
//-------------------------------------------------------------------
$sql = ' SELECT '
. ' tbl_product_category.`product_category_lft_order` AS `product_category_lft_order`, '
. ' tbl_product_category.`product_category_rgt_order` AS `product_category_rgt_order` '
. ' FROM `tbl_product_category` AS `tbl_product_category` '
. ' WHERE tbl_product_category.`pk_product_category_id`=\''.$startNode.'\' '
. ' ORDER BY tbl_product_category.`product_category_lft_order` ASC '
. ' LIMIT 0,1 ';
$result =$this->_db->query($sql);
$row = $result->fetchRow(DB_FETCHMODE_ASSOC);
$startNodeLft=$row['product_category_lft_order'];
$startNodeRgt=$row['product_category_rgt_order'];
// Auslesen aller Child-Nodes von $startNode
//-------------------------------------------------------------------
$sql = ' SELECT '
. ' tbl_product_category.`product_category_lft_order` AS `product_category_lft_order`, '
. ' tbl_product_category.`product_category_rgt_order` AS `product_category_rgt_order`, '
. ' tbl_product_category.`testtext` AS `testtext` '
. ' FROM `tbl_product_category` AS `tbl_product_category` '
. ' WHERE '
. ' tbl_product_category.`product_category_lft_order`>=\''.$startNodeLft.'\' '
. ' AND tbl_product_category.`product_category_lft_order`<=\''.$startNodeRgt.'\' '
. ' ORDER BY tbl_product_category.`product_category_lft_order` ASC ';
$result =$this->_db->query($sql);
// Gefundene Child-Nodes durchlaufen
//-------------------------------------------------------------------
while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC)) {
// Prüfen, ob der (Hilfs-) layerStack bereits gefüllt ist
// (Dies ist erst ab dem zweiten Durchlauf der Fall)
//-------------------------------------------------------------------
if (count($layerStack)>0) {
// Prüfen, ob dem Layer-Stack das letzte Element "weggepoppt" werden soll :o)
// (Entspricht dem Retour-Sprung in eine Parent-Ebene)
//-------------------------------------------------------------------
while ($layerStack[count($layerStack)-1]<$row['product_category_rgt_order']) {
array_pop($layerStack);
}
}
// Gefundene Knoten mit Einrückungen anzeigen
//-------------------------------------------------------------------
echo str_repeat(' --- | ',count($layerStack)).$row['testtext']."<br>";
// Den aktuellen Node auf den Stack legen (LIFO)
//-------------------------------------------------------------------
$layerStack[] = $row['product_category_rgt_order'];
}
}
Code:
ROOT
--- | Auto
--- | --- | Opel
--- | --- | Audi
--- | Motorrad
--- | --- | Yamaha
--- | --- | --- | YZF R1
--- | --- | --- | Tomcat
Anlagen:
1. Das hier verwendete Beispiel als Diagramm zum leichteren Verständnis
2. Ein Snapshot der verwendeten Test-Tabelle "tbl_product_category"
Vielen Dank vorab für die Hilfe.. ich steh wahrscheinlich nach dem langen Arbeitstag im Moment nur total auf der Leitung
Ciao,
Mike
Anhänge
Zuletzt bearbeitet: