Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   [PHP] Datensätze als Baum darstellen (https://www.delphipraxis.net/108794-%5Bphp%5D-datensaetze-als-baum-darstellen.html)

Matze 19. Feb 2008 18:48


[PHP] Datensätze als Baum darstellen
 
Hallo,

ich versuche gerade, Kategorie-Namen als Baum anzeigen zu lassen.

Meine Datenbanktabelle hat grob diesen Aufbau:

Code:
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
Der Baum sollte also am Ende so darstellbar sein:

Code:
Pflanzen
    Löwenzahn
Tiere
    Säugetiere
        Giraffe
        Maus
        Katze
    Vögel
        Adler
Natürlich sollten die Ebenen beliebig tief verschachtelt sein können.

Ich habe es versucht, wie hier beschrieben, doch diese Funktion gibt den Baum Stück-für-Stück aus und das möchte ich nicht. Ich hätte das gerne in einem Array zurückgegeben (Aufbau wie der Baum oben), damit ich mit diesem weiterarbeiten kann.

Wie muss das genau aussehen?

Grüße

cruiser 19. Feb 2008 18:57

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:
// 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;
}
}
}
}
zugegeben... ist jetzt seeeeehr WordPress-Spezifisch ;)

Matze 19. Feb 2008 19:04

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

omata 19. Feb 2008 19:09

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

Matze 19. Feb 2008 19:11

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. ;)

bluesbear 19. Feb 2008 19:35

Re: [PHP] Datensätze als Baum darstellen
 
Zitat:

Zitat von Matze
(...) Ich hätte das gerne in einem Array zurückgegeben (Aufbau wie der Baum oben), damit ich mit diesem weiterarbeiten kann. (...)

Ich verstehe die Aufgabenstellung nicht so ganz - Einen Baum in einem Array darstellen? :gruebel: Wie soll das Array denn aussehen?

Matze 19. Feb 2008 19:49

Re: [PHP] Datensätze als Baum darstellen
 
Hallo Klaus

Zitat:

Zitat von bluesbear
Ich verstehe die Aufgabenstellung nicht so ganz - Einen Baum in einem Array darstellen? :gruebel:

Nein, Ich möchte Daten so in ein Array packen, dass man daraus leicht einen Baum beim Durchlaufen des Arrays darstellen kann. Vielleicht habe ich mich in dieser Hinsicht schlecht ausgedrückt.

Zitat:

Zitat von bluesbear
Wie soll das Array denn aussehen?

Was da am Geeignetsten ist, weiß ich nicht, ich denke aber etwas in der Art:

Code:
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
                )
            )
)
Grüße

mkinzler 19. Feb 2008 20:21

Re: [PHP] Datensätze als Baum darstellen
 
Die Darstellung des Arrays könnte man mit Hilfe eines Templates erleichtern

Matze 19. Feb 2008 20:22

Re: [PHP] Datensätze als Baum darstellen
 
Zitat:

Zitat von mkinzler
Die Darstellung des Arrays könnte man mit Hilfe eines Templates erleichtern

Ein Template-System nutze ich und das ist mit ein Grund, wieso ist die Daten zuerst in einem Array haben möchte. :thumb:

cruiser 19. Feb 2008 20:28

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:
<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>
Ausgabe:

Code:
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
                                        )

                                )

                        )

                )

        )

)
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 ;)

Edit (13:40):
Hab alles noch ein wenig optimiert. Viel Spass mit.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:51 Uhr.
Seite 1 von 4  1 23     Letzte »    

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz