![]() |
[PHP] Datensätze als Baum darstellen
Hallo,
ich versuche gerade, Kategorie-Namen als Baum anzeigen zu lassen. Meine Datenbanktabelle hat grob diesen Aufbau:
Code:
Der Baum sollte also am Ende so darstellbar sein:
id | parent_id | name
---------------------------- 0 | -1 | Pflanzen 1 | -1 | Tiere 2 | 6 | Giraffe 3 | 6 | Maus 4 | 0 | Löwenzahn 5 | 6 | Katze 6 | 1 | Säugetiere 7 | 1 | Vögel 8 | 7 | Adler
Code:
Natürlich sollten die Ebenen beliebig tief verschachtelt sein können.
Pflanzen
Löwenzahn Tiere Säugetiere Giraffe Maus Katze Vögel Adler Ich habe es versucht, wie ![]() Wie muss das genau aussehen? Grüße |
Re: [PHP] Datensätze als Baum darstellen
Hallo...
ich nehm Wordpress für eine Website und da hab ichs fürs Menü auch so eine Struktur mit einer eignen Funktion geparsed... evtl. hilft dir das ja...
Code:
zugegeben... ist jetzt seeeeehr WordPress-Spezifisch ;)
// special styled menu
function SahaPrintMenu($parent="0", $path=null, $level=0) { global $wpdb; if (! isset($path) ) { $path = explode("/", $_SERVER["REQUEST_URI"]); array_shift($path); } $actpath= "/"; if ($level > 0) { $before = "<h3 class=\"level".$level."\">"; $after = "</h3>"; for ($i = 0; $i < $level; $i++) { $actpath .= "$path[$i]/"; } } else { $before = "<h2>"; $after = "</h2>"; } $nosubs = array( 0 => array("mitglieder", "galerien"), 1 => array("galerie-archiv") ); // end $nosubs $query = " SELECT post_title,post_name,id FROM $wpdb->posts WHERE post_type=\"page\" AND post_parent=\"$parent\" AND post_status=\"publish\" ORDER BY menu_order "; $result = $wpdb->get_results($query, ARRAY_A); foreach ($result as $row) { if (count($wpdb->get_results("SELECT id FROM $wpdb->posts WHERE post_parent=\"$row[id]\"", ARRAY_A))) { // hat unterpunkte if (isset($nosubs[$level])) { // irgendwas soll keine unterpunkte haben if (in_array($row[post_name], $nosubs[$level])) { // dieses soll keine unterpunkte haben if ($row[post_name] == $path[$level]) { // aktuell echo $before."<a class=\"currlink\" href=\"$actpath".$row[post_name]."\">".$row[post_title]."</a>".$after; } else { // nicht aktuell echo $before."<a href=\"$actpath".$row[post_name]."\">".$row[post_title]."</a>".$after; } } else { // dieses darf unterpunkte haben if ($row[post_name] == $path[$level]) { //aktuell if (isset($path[$level + 1])) { // pfad geht tiefer echo $before."<a href=\"$actpath".$row[post_name]."\">".$row[post_title]."</a>".$after; } else { // pfad geht nicht tiefer echo $before."<a class=\"currlink\" href=\"$actpath".$row[post_name]."\">".$row[post_title]."</a>".$after; } SahaPrintMenu($row[id], $path, $level + 1); } else { // nicht aktuell echo $before."<a href=\"$actpath".$row[post_name]."\">".$row[post_title]."</a>".$after; } } } else { // alles soll Unterpunkte haben if ($row[post_name] == $path[$level]) { // aktuell if (isset($path[$level + 1])) { // pfad geht tiefer echo $before."<a href=\"$actpath".$row[post_name]."\">".$row[post_title]."</a>".$after; } else { // pfad geht nicht tiefer echo $before."<a class=\"currlink\" href=\"$actpath".$row[post_name]."\">".$row[post_title]."</a>".$after; } SahaPrintMenu($row[id], $path, $level + 1); } else { // nicht aktuell echo $before."<a href=\"$actpath".$row[post_name]."\">".$row[post_title]."</a>".$after; } } } else { // hat keine unterpunkte if ($row[post_name] == $path[$level]) { // aktuell echo $before."<a class=\"currlink\" href=\"$actpath".$row[post_name]."\">".$row[post_title]."</a>".$after; } else { // nicht aktuell echo $before."<a href=\"$actpath".$row[post_name]."\">".$row[post_title]."</a>".$after; } } } } |
Re: [PHP] Datensätze als Baum darstellen
Hallo Ronny,
danke fürs Heraussuchen. Wie ich das beim groben Überfliegen feststellen kann, macht dein Code nichts anderes als der auf der verlinken Website, nämlich in der Schleife nacheinander die Menüeinträge auszugeben. Und genau das möchte ich ja nicht. ;) Grüße |
Re: [PHP] Datensätze als Baum darstellen
Wenn das in einem Rutsch erzeugt werden soll, solltest du uns nochmal erzählen welche Datenbank du einsetzt.
Gruss Thorsten |
Re: [PHP] Datensätze als Baum darstellen
Hallo Thorsten,
das hatte ich vergessen zu schreiben: MySQL 5.0.26 Grüße Edit: Es muss auch nicht super performant sein. Nur die Funktion zum Abarbeiten des Arrays sollte einigermaßen flott arbeiten, doch über die mach ich mir noch keine Gedanken. Erst einmal brauche ich das Array, dann schaue ich mal, ob ich das rekursiv durchgehen kann. Wenn nicht, dann frage ich hier weiter. ;) |
Re: [PHP] Datensätze als Baum darstellen
Zitat:
|
Re: [PHP] Datensätze als Baum darstellen
Hallo Klaus
Zitat:
Zitat:
Code:
Grüße
array (
[0] => Pflanzen = array ( [0] => Löwenzahn ) [1] => Tiere = array ( [0] => Säugetiere = array ( [0] => Giraffe [1] => Maus [2] => Katze ) [1] => Vögel = array ( [0] => Adler ) ) ) |
Re: [PHP] Datensätze als Baum darstellen
Die Darstellung des Arrays könnte man mit Hilfe eines Templates erleichtern
|
Re: [PHP] Datensätze als Baum darstellen
Zitat:
|
Re: [PHP] Datensätze als Baum darstellen
Ich schau mal drüber... sollte nicht das Prob sein aus einem Datensatz einen Baum zu machen ;)
Edit (4:33): Okay... eigentlich wollt ich vor einer Stunde so langsam pennen, da kam mir ein Geistesblitz. Wenn du einen Datensatz hast ist es allerdings wichtig, dass die ID immer in der ersten Spalte steht, oder du passt die Vorverarbeitung des Datensatzes an.
Code:
Ausgabe:
<html>
<head> <title>DataSet 2 Tree - Test</title> <style> .code { margin-bottom: 10px; margin-top: 0; border: 1px solid black; } </style> </head> <body><?php // Test-Datenmenge $dataset = array( array("id"=>1, "parent"=>0, "text"=>"Test1", "data"=>"Data1"), array("id"=>2, "parent"=>0, "text"=>"Test2", "data"=>"Data2"), array("id"=>3, "parent"=>1, "text"=>"Test3", "data"=>"Data3"), array("id"=>4, "parent"=>2, "text"=>"Test4", "data"=>"Data4"), array("id"=>5, "parent"=>1, "text"=>"Test5", "data"=>"Data5"), array("id"=>6, "parent"=>1, "text"=>"Test6", "data"=>"Data6"), array("id"=>7, "parent"=>4, "text"=>"Test7", "data"=>"Data7"), array("id"=>8, "parent"=>4, "text"=>"Test8", "data"=>"Data8"), array("id"=>9, "parent"=>3, "text"=>"Test9", "data"=>"Data9") ); // rekursives füllen eines Trees aus einer Datenmenge // die & vor den variablen sind Zeigerangaben, damit auch // rauskommt was gewünscht wird function filltree(&$node, &$ds, $id=0) { // Datenmenge durchgehen (Tree-Root ist 0) foreach ($ds as $key=>$data) { // Wenn der parent mit der ID der zu füllenden Node übereinstimmt // eine Subnode erstellen if ($data["parent"] == $id) { // Zuordnung von Nutzdaten zu ID $node[$data["id"]] = array("text" => $data["text"], "data" => $data["data"]); // rekursiv füllen filltree($node[$data["id"]]["childs"], $ds, $data["id"]); // wenn es doch keine Kinder gab, den "childs"-Unterpunkt // wieder entfernen if (count($node[$data["id"]]["childs"]) == 0) { unset($node[$data["id"]]["childs"]); } // eingetragenes Node aus der Datenmenge entfernen unset($ds[$key]); } } } // das eigentliche befüllen $tree wird dabei gleich mit definiert filltree($tree, $dataset); // Debug Ausgabe echo "[b]print_r(\$tree):[/b]<pre class='code'>".print_r($tree, true)."</pre>"; ?></body> </html>
Code:
Das ganze hat aber vermutlich nicht die beste Laufzeit... durch eliminierung der bereits im Baum eingetragenen Nodes sollte es bei grossen Bäumen performanter werden. Aber ich bin doch nun etwas Müde ;)
Array
( [1] => Array ( [text] => Test1 [data] => Data1 [childs] => Array ( [3] => Array ( [text] => Test3 [data] => Data3 [childs] => Array ( [9] => Array ( [text] => Test9 [data] => Data9 ) ) ) [5] => Array ( [text] => Test5 [data] => Data5 ) [6] => Array ( [text] => Test6 [data] => Data6 ) ) ) [2] => Array ( [text] => Test2 [data] => Data2 [childs] => Array ( [4] => Array ( [text] => Test4 [data] => Data4 [childs] => Array ( [7] => Array ( [text] => Test7 [data] => Data7 ) [8] => Array ( [text] => Test8 [data] => Data8 ) ) ) ) ) ) Edit (13:40): Hab alles noch ein wenig optimiert. Viel Spass mit. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:18 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz