Rainer der Neue: Array als LISTEN UL LI ausgeben....

Ich versuche mich seit kurzer Zeit mit PHP. Aber leide rstosse ich immer wieder an Grenzen.
So wie jetzt auch:

Ich habe in meiner Datenbank die auf MYSQL läuft die Einträge nach

* id | parent | name
* -------------------
*  1 |      0 | A
*  2 |      0 | B
*  3 |      0 | C
*  4 |      1 | Aa
*  5 |      1 | Ab
*  6 |      2 | Ba

gemacht, wie auf der Seite

http://www.phpbar.de/w/Baumstruktur_aus_DB_in_Array_abbilden

beschrieben.

Jetzt habe ich aber ein Problem. Die Ausgabe erfolgt in einem Array

  
$items = array();  
  
$result = mysql_query('SELECT * FROM `table` ORDER BY `parent`');  
  
while (($row = mysql_fetch_assoc($result)) !== false) {  
    // wir wollen die IDs als Zahl und nicht als Zeichenkette  
    $row['id']     = (int) $row['id'];  
    $row['parent'] = (int) $row['parent'];  
  
    // ablegen in unserem Array  
    $items[$row['id']] = $row;  
  
    // verlinken mit dem Elternteil  
    $items[$row['parent']]['childs'][$row['id']] =& $items[$row['id']];  
}  

// nur den Ast mit der ID 1 ausgeben
print_r($items[1]);

Wenn ich es so ausgebe, bekomme ich den ganzen Inhalt des Arrays angezeigt.
Ich möchte nun dieses Arry in eine Listen Funktion UL LI umwandlen.

Kann mir jemand vieleicht einen Hinweis geben wie ich da hin komme.

  1. Du hast in $items[1]

    Array  
    (  
        [id] => 1  
        [parent] => 0  
        [name] => A  
        [childs] => Array  
            (  
                [4] => Array  
                    (  
                        [id] => 4  
                        [parent] => 1  
                        [name] => Aa  
                    )  
                [5] => Array  
                    (  
                        [id] => 5  
                        [parent] => 1  
                        [name] => Ab  
                    )  
            )  
    )
    

    Und Du möchtest sowas wie

    <ul>  
      <li>Id: 1</li>  
      <li>parent: 0</li>  
      <li>name: A</li>  
      <li>childs:  
        <ul>  
          <li>Array  
            <ul>  
              <li>id: 4</li>  
              <li>parent: 1</li>  
              <li>name: Aa</li>  
            </ul>  
          </li>  
          <li> <!-- ... -->  
          </li>  
        </ul>  
      </li>  
    </ul>
    

    Sehe ich das richtig?

    Nun, was Du suchst, ist eine Funktion, die sich selbst aufruft. Pseudo code:

    function CreateList($array){  
      
       // starte Liste, e.g. $html = "<ul>";  
      
       // iteriere über array, e.g. foreach($array as $item)  
       // wenn item ein array ist, dann $html.= CreateList($item);  
       // andernfalls packe füge $item als <li> der Liste hinzu  
      
       // schließe Liste  
      
       // gebe Liste zurück, e.g. return $html;  
      
    }
    

    Ich versuche mich seit kurzer Zeit mit PHP. Aber leide rstosse ich immer wieder an Grenzen.

    An welche Grenzen stößt Du denn genau?

    Cheers,
    Baba

    --
    Baba kommt von Basketball
    1. Hallo Baba!

      Mein ERSTES Problem ist, das ich nur die Variable  [name] => A in meinem Array haben möchte. aber ich glaube er braucht die anderen werte zum sortieren, oder liege ich da falsch.

      dann, du meist es so

      starte Liste, e.g. $html = "<ul>";
      eine  foreach($array as $item) Schleife
      und dann Zeilenweise in die $html.

      1. Mein ERSTES Problem ist, das ich nur die Variable  [name] => A in meinem Array haben möchte. aber ich glaube er braucht die anderen werte zum sortieren, oder liege ich da falsch.

        Ja, da liegst Du falsch. Das sortieren der Einträge geschieht über die SQL Query über ORDER BY.
        Wenn Du *nur* die Namen brauchst, warum dann nicht:

          
        while (($row = mysql_fetch_assoc($result)) !== false) {  
            // name ablegen in unserem Array  
            $items[] = $row["name"];  
        }
        

        Dein ZWEITES Problem ist, dass Du Dich nicht so klar ausdrückst.

        dann, du meist es so

        Könntest Du etwas auf Deine Rechtschreibung achten, bitte?

        starte Liste, e.g. $html = "<ul>";
        eine  foreach($array as $item) Schleife
        und dann Zeilenweise in die $html.

        Ja. Wichtig ist dabei, dass Du $html.= und nicht $html= schreibst, da Letzteres $html immer überschreibt, während Ersteres eine Stringverkettung ist.

        Cheers,
        Baba

        --
        Baba kommt von Basketball
        1. while (($row = mysql_fetch_assoc($result)) !== false) {
              // name ablegen in unserem Array
              $items[] = $row["name"];
          }

            
          Ja, das habe ich mir auch gedacht. Aber wenn ich das so mache  
            
            
            
          ~~~php
          while (($row = mysql_fetch_assoc($result)) !== false) {  
              // wir wollen die IDs als Zahl und nicht als Zeichenkette  
              $row['id']     = (int) $row['id'];  
              $row['parent'] = (int) $row['parent'];  
            
              // ablegen in unserem Array  
              // $items[$row['id']] = $row;  
              $items[$row['id']] = $row['name'];  
            
              // verlinken mit dem Elternteil  
              $items[$row['parent']]['childs'][$row['id']] =& $items[$row['id']];  
          }  
          
          

          bekomme ich die Fehlermeldung

          Warning: Illegal string offset 'childs' in xxxxxxxxxxxxxxxxxx   on line 42

          Fatal error: Cannot use string offset as an array in xxxxxxxxxxxxxxxxxxxxxxxxx on line 42

          Die Zeile 42 bezieht sich auf die letzte Zeile im Code

          $items[$row['parent']]['childs'][$row['id']] =& $items[$row['id']];

          ich denke das er ja hier noch die ganzen anderen Daten braucht zum sortieren und ich diese ihm ja vorenthalte wenn ich bei

          $items[$row['id']] = $row['name'];

          nur eben den Namen übergebe!

          Könntest Du etwas auf Deine Rechtschreibung achten, bitte?

          ich werde mein bestes versuchen, sorry!

          1. Warning: Illegal string offset 'childs' in xxxxxxxxxxxxxxxxxx   on line 42

            Ich ein Problem darin, dass in der Zeile
            $items[$row['id']] = $row['name'];
            an eines der Elemente bereits ein Wert (string) vergeben wird.

            Denn Wenn jetzt da jetzt z.B. plötzlich ein bereits existierendes $items[1] mit dem Inhalt 'foo' hergenommen wird und
            $items[1]['childs'][0] =& $items[0] versucht wird, dann sieht das jetzt für mich mal so aus, als wäre die erste Fehlermeldung "Warning: Illegal string offset 'childs' in xxxxxxxxxxxxxxxxxx   on line 42" plausibel.

            Jörg Reinholz

            1. Warning: Illegal string offset 'childs' in xxxxxxxxxxxxxxxxxx   on line 42

              Ich ein Problem darin, dass in der Zeile
              $items[$row['id']] = $row['name'];
              an eines der Elemente bereits ein Wert (string) vergeben wird.

              So ist es auch:

              test.php:

              <?php  
              $items[0]='bar';  
              $items[1] = 'foo';  
              $items[1]['childs'][0] =& $items[0];  
              
              

              Ausführen ... und:

              PHP Warning:  Illegal string offset 'childs' in /tmp/test.php on line 4

              Warning: Illegal string offset 'childs' in /tmp/test.php on line 4
              PHP Fatal error:  Cannot use string offset as an array in /tmp/test.php on line 4

              Fatal error: Cannot use string offset as an array in /tmp/test.php on line 4

              Jörg Reinholz

              1. So ist es auch:

                test.php:

                <?php

                $items[0]='bar';
                $items[1] = 'foo';
                $items[1]['childs'][0] =& $items[0];

                
                >   
                > Ausführen ... und:  
                >   
                > PHP Warning:  Illegal string offset 'childs' in /tmp/test.php on line 4  
                >   
                > Warning: Illegal string offset 'childs' in /tmp/test.php on line 4  
                > PHP Fatal error:  Cannot use string offset as an array in /tmp/test.php on line 4  
                  
                  
                Könnt ihr mir auch sagen wie ich das Problem lösen kann. Ich verstehe nämlich nicht ganz wie ich weiter vorgehen kann.  
                
                
                1. Könnt ihr mir auch sagen wie ich das Problem lösen kann. Ich verstehe nämlich nicht ganz wie ich weiter vorgehen kann.

                  Hm. Wolltest Du nicht eher sowas?

                  <?php  
                  $csv=trim('  
                  1|0|A  
                  2|0|B  
                  3|0|C  
                  4|1|Aa  
                  5|1|Ab  
                  6|2|Ba  
                  ');  
                  $arCSV=explode("\n", $csv);  
                    
                  $items=array();  
                    
                  foreach ($arCSV as $lineCSV) {  
                    $row=array();  
                    list($id, $parent, $name)=explode('|', trim($lineCSV));  
                    $row['id']     = (int) $id;  
                    $row['parent'] = (int) $parent;  
                    $row['name']   = $name;  
                    
                    // ablegen in unserem Array  
                    $items[$row['id']] = $row;  
                    
                      // verlinken mit dem Elternteil  
                      if ( $row['parent'] ) { # wenn 0 gibt es kein Elternteil  
                           $items[$row['id']]['his_parent'] =& $items[$row['parent']];  
                      }  
                  }  
                    
                  print_r($items[5]);  
                    
                  
                  
                  fastix@trainer:/tmp$ php test.php  
                  Array  
                  (  
                      [id] => 5  
                      [parent] => 1  
                      [name] => Ab  
                      [his_parent] => Array  
                          (  
                              [id] => 1  
                              [parent] => 0  
                              [name] => A  
                          )  
                    
                  )  
                  
                  
                  1. Ich schiebe mal die Ausgaben für andere Daten nach:

                    Daten;

                    $csv=trim('  
                    1|0|A  
                    2|0|B  
                    3|1|AA  
                    4|2|AB  
                    5|3|AAA  
                    6|4|ABA  
                    ');  
                    
                    

                    Gesamter Array:

                      
                    Array  
                    (  
                        [1] => Array  
                            (  
                                [id] => 1  
                                [parent] => 0  
                                [name] => A  
                            )  
                      
                        [2] => Array  
                            (  
                                [id] => 2  
                                [parent] => 0  
                                [name] => B  
                            )  
                      
                        [3] => Array  
                            (  
                                [id] => 3  
                                [parent] => 1  
                                [name] => AA  
                                [his_parent] => Array  
                                    (  
                                        [id] => 1  
                                        [parent] => 0  
                                        [name] => A  
                                    )  
                      
                            )  
                      
                        [4] => Array  
                            (  
                                [id] => 4  
                                [parent] => 2  
                                [name] => AB  
                                [his_parent] => Array  
                                    (  
                                        [id] => 2  
                                        [parent] => 0  
                                        [name] => B  
                                    )  
                      
                            )  
                      
                        [5] => Array  
                            (  
                                [id] => 5  
                                [parent] => 3  
                                [name] => AAA  
                                [his_parent] => Array  
                                    (  
                                        [id] => 3  
                                        [parent] => 1  
                                        [name] => AA  
                                        [his_parent] => Array  
                                            (  
                                                [id] => 1  
                                                [parent] => 0  
                                                [name] => A  
                                            )  
                      
                                    )  
                      
                            )  
                      
                        [6] => Array  
                            (  
                                [id] => 6  
                                [parent] => 4  
                                [name] => ABA  
                                [his_parent] => Array  
                                    (  
                                        [id] => 4  
                                        [parent] => 2  
                                        [name] => AB  
                                        [his_parent] => Array  
                                            (  
                                                [id] => 2  
                                                [parent] => 0  
                                                [name] => B  
                                            )  
                      
                                    )  
                      
                            )  
                      
                    )  
                      
                    
                    
                    1. Kommen wir zur Liste.

                      Also statt print_r brauchst Du eine rekursiv aufgerufene Funktion, weil Du ja ebentuell wieder einen Array als Element hast.

                      $dummy=print_my_list ($items[5]); # statt print_r($items[5]);  
                        
                        
                      function print_my_list($ar, $t=0) {  
                          $rueck=''; for ($i=0;$i<$t;$i++)  { $rueck = $rueck . "    "; } #Nur für schöneres Ergebnis  
                          print "\n$rueck<ul>";  
                          print "\n$rueck    <li>id: "   . $ar['id'] . "</li>";  
                          print "\n$rueck    <li>name: " . $ar['name'] . "</li>";  
                          if ( isset($ar['his_parent']) ) {  
                              print "\n$rueck    <li>";  
                      	print_my_list($ar['his_parent'], $t+2); # Ja, Die ruft sich selbst auf!  
                                                                      # Deswegen "rekursiv aufgerufene Funktion"  
                      	print "\n$rueck    </li>";	  
                          }  
                          print "\n$rueck</ul>";  
                      }  
                      
                      

                      Ergebnis:

                      <ul>  
                          <li>id: 5</li>  
                          <li>name: AAA</li>  
                          <li>  
                              <ul>  
                                  <li>id: 3</li>  
                                  <li>name: AA</li>  
                                  <li>  
                                      <ul>  
                                          <li>id: 1</li>  
                                          <li>name: A</li>  
                                      </ul>  
                                  </li>  
                              </ul>  
                          </li>  
                      </ul>