hansdampf: Verschachtelte Liste mit php erzeugen

Hallo!
Ich suche eine Möglichkeit, aus einer Datenbank heraus mit php
eine verschachtelte Liste zu erzeugen.
Leider sind meine Versuche bisher alle fehl geschlagen.
(Liste wurde nicht  korekt aufgebaut/verschachtelt)
Meine Datenbank-Struktur sieht folgendermaßen aus:

id parent name(des Listenpunktes)
1  0      Menüpunkt_eins
2  1      Unterpunkt_eins
3  2      Unter_unterpunkt_eins
4  0      Menüpunkt_zwei

Daraus müßte also z.B. folgende Liste erstellt werden:

<ul>
 <li>Menüpunkt_eins
  <ul>
   <li>Unterpunkt_eins
    <ul>
     <li>Unter_unterpunkt_eins</li>
    </ul>
   </li>
   </ul>
  </li>
  <li>Menüpunkt_zwei</li>
</ul>

Ich wäre über jede Hilfe froh!

Dennis

  1. echo $begrüßung;

    Ich suche eine Möglichkeit, aus einer Datenbank heraus mit php
    eine verschachtelte Liste zu erzeugen.
    Leider sind meine Versuche bisher alle fehl geschlagen.
    (Liste wurde nicht  korekt aufgebaut/verschachtelt)

    Wo lagen denn die Probleme genau? Klappte das Auslesen aus der Datenbank nicht? Fiel dir kein gescheites Format ein, wie die Daten aus der DB temporär abgelegt werden, bevor die Liste daraus erstellt werden soll? Hattest du Schwierigkeiten beim Erzeugen des HTML-Codes aus den Daten?

    echo "$verabschiedung $name";

    1. echo $begrüßung;

      Ich suche eine Möglichkeit, aus einer Datenbank heraus mit php
      eine verschachtelte Liste zu erzeugen.
      Leider sind meine Versuche bisher alle fehl geschlagen.
      (Liste wurde nicht  korekt aufgebaut/verschachtelt)

      Wo lagen denn die Probleme genau? Klappte das Auslesen aus der Datenbank nicht? Fiel dir kein gescheites Format ein, wie die Daten aus der DB temporär abgelegt werden, bevor die Liste daraus erstellt werden soll? Hattest du Schwierigkeiten beim Erzeugen des HTML-Codes aus den Daten?

      echo "$verabschiedung $name";

      Hallo!
      Nein, ich habe einfach ein kleines Programm geschrieben, welches
      die Daten ausliest und daraus die Liste erzeugen sollte.
      Das auslesen klappte ohne Probleme, ich krieg es nur nicht hin, eine valide Liste zu erstellen.
      Ich vermute mal, daß man das irgendwie rekursiv lösen muß..
      Bei meinen Versuchen kamen zwar auch listen raus, diese waren aber nie valide. Also z.b. li oder ul nicht geschlossen oder nicht richtig verschachtelt etc.
      Mein Versuch bis jetzt sieht so aus:

      <?php

      function makemenu( $parent = '' )

      {

      if( $parent == '' )

      {

      print "<ul id="containerul">\n";

      }

      else

      {

      print "<ul>\n";

      }

      $result = mysql_query ("
            SELECT
              *
            FROM
              menu
            WHERE
              parent = '".$parent."';
            ");

      while( $row = mysql_fetch_object($result) )

      {

      print "<li>".$row->name."</li>";

      makemenu( $row->id );

      }

      print "</ul>";

      }

      ?>

      1. Hi,
        zunächst mal würde ich empfehlen, das Menü in ein zweidimensionales Array einzulesen (hierzu finde ich die Art der Speicherung in der Datenbank allerdings unpraktisch.
        Ich habe z.B. auf einer Seite ein solches Array $nav mit den erforderlichen Angaben zur Navigation. Zusätzlich habe ich vorab noch ein Array $subnav mit der hieraus berechneten Anzahl der Untermenüpunkte  angelegt. Der Code sieht dann - vereinfacht - so aus:

        $menu = '  <ul>'.$cr;  
        for($i=0; $i<count($nav); $i++) {  
          $menu .= '    <li><a href="'.$nav[$i][1].'">'.$nav[$i][2].'</a>';  
          if($subnav[$i]) {  
            $menu .= '<ul>'.$cr;  
            for($ii=0; $ii<$subnav[$i]; $ii++) {  
              $menu .= '      <li><a href="'.$nav[$i][$ii+$navinfo][1].'">'.$nav[$i][$ii+$navinfo][2].'</a></li>'.$cr;  
            }  
            $menu .= '    </ul>';  
          }  
          $menu .= '</li>'.$cr;  
        }  
        $menu .= '  </ul>'.$cr;
        

        freundliche Grüße
        Ingo

        1. Lieber Ingo,

          $menu = ' <ul>'.$cr;

          ich vermute einmal, dass $cr bei Dir irgendwo vorher definiert worden ist? Bei mir sähe das so aus:
          $cr = "\r\n";

          Liebe Grüße aus Ellwangen,

          Felix Riesterer.

          1. Hi,

            ich vermute einmal, dass $cr bei Dir irgendwo vorher definiert worden ist? Bei mir sähe das so aus:
            $cr = "\r\n";

            Ja sicher - schrieb ich kürzlich auch mal hier an anderer Stelle: $cr = chr(13).chr(10);
            Ds hat u.a. den Vorteil, dass ich das bei Bedarf leicht ändern kann, z.B. auf chr(10) oder auch '' - für das gesamte Script oder auch nur für bestimmte Funktionen.

            freundliche Grüße
            Ingo

        2. Hi,
          zunächst mal würde ich empfehlen, das Menü in ein zweidimensionales Array einzulesen (hierzu finde ich die Art der Speicherung in der Datenbank allerdings unpraktisch.
          Ich habe z.B. auf einer Seite ein solches Array $nav mit den erforderlichen Angaben zur Navigation. Zusätzlich habe ich vorab noch ein Array $subnav mit der hieraus berechneten Anzahl der Untermenüpunkte  angelegt. Der Code sieht dann - vereinfacht - so aus:

          $menu = '  <ul>'.$cr;

          for($i=0; $i<count($nav); $i++) {
            $menu .= '    <li><a href="'.$nav[$i][1].'">'.$nav[$i][2].'</a>';
            if($subnav[$i]) {
              $menu .= '<ul>'.$cr;
              for($ii=0; $ii<$subnav[$i]; $ii++) {
                $menu .= '      <li><a href="'.$nav[$i][$ii+$navinfo][1].'">'.$nav[$i][$ii+$navinfo][2].'</a></li>'.$cr;
              }
              $menu .= '    </ul>';
            }
            $menu .= '</li>'.$cr;
          }
          $menu .= '  </ul>'.$cr;

          
          >   
          > freundliche Grüße  
          > Ingo  
            
          Danke erstmal!  
          Ich habe mir das gerade mal angeschaut, aber so wirklich blicke ich da nicht durch..  
          Ist mein Ansatz da nicht weniger umständlich?  
          Es soll nur eine kleine Liste mit wahrscheinlich nicht mehr als 10 Punkten mit einigen Unterpunkten werden.  
          Daher braucht das nicht sehr aufwendig sein.  
          Es funktioniert ja teilweise auch schon.  
          Nur hab ich halt irgendwo einen kleinen Fehler, den ich nicht finde...
          
          1. Hi,

            Ich habe mir das gerade mal angeschaut, aber so wirklich blicke ich da nicht durch..

            dann erstelle doch einfach aus Deinen Daten ein verschachteltes Array $nav und probiere den Code aus.

            Ist mein Ansatz da nicht weniger umständlich?

            Ja, aber so einfach funktioniert das halt nicht. Du brauchst eine äußere Schleife für die Hauptmenüpunkte und eine innere für die Unterpunkte. Diese innere Schleife muß vor dem </li> kommen und die verschachtelte ul generieren. Nichts anderes macht mein Script.

            freundliche Grüße
            Ingo

  2. Hallo,

    id parent name(des Listenpunktes)
    1  0      Menüpunkt_eins
    2  1      Unterpunkt_eins
    3  2      Unter_unterpunkt_eins
    4  0      Menüpunkt_zwei

    Das Problem ist schon hier.
    Hättest du besser in der Art gemacht:

    id parent sub
    1   0      0
    2   1      1
    3   2      1
    4   0      0

    So weisst du dass id 2+3 Unterkategorien von ID 1 sind.

    Ansonsten funktioniert deine Methode auch, macht aber viel mehr
    Arbeit beim Auslesen, weil du dich immer auf die IDs oberhalb beziehen muss. Also recht unflexibel.

    Stefan

    1. Hi,

      Hättest du besser in der Art gemacht:

      id parent sub
      1   0      0
      2   1      1
      3   2      1

      die dritte Spalte ist überflüssig.
      Anhand von parent kann man ermitteln, ob und welches Element darüber liegt.
      Hauptmenüpunkte -> parent=0
      Unterpunkte von 1 -> parent=1
      Evtl. Weitere Unterpunkte dieses Unterpunktes hätten dann den jeweiligen Unterpunkt als parent.

      freundliche Grüße
      Ingo