Greener: Rekursive Funktion und Speichern im assoziativen Array

Hallo Forumfreunde, ich habe gerade ein bisschen mit PHP zu kämpfen und vielleicht könnt ihr mir ja helfen.

Ich habe ein Verzeichnis und in diesem Verzeichnis wieder Unterverzeichnise mit Dateien also eine komplexe Verzeichnisstruktur mit unendlich vielen möglichen Ebenen.

Der Hintergrund ist, dass ich diese Verzeichnisstruktur nachher auf der Website als Menü ausgeben möchte. Jeder Ordner ist dann ein Menüpunkt, jeder Unterordner ein weiterer Menüpunkt und jede Datei auch ein Menüpunkt.

Dabei habe ich nun folgende Probleme: wie speichere ich die Verzeichnisstruktur und wie kann ich im assoziativen Array speichern, ob eine Datei oder ein Verzeichnis vorliegt.

Nachher sollte das ganze so aussehen:

Array:

ordner1
   ordner2
      ordner3
         textdatei1
         textdatei2
      textdatei3
   ordner4
      textdatei4
   ordner5
   ordner6
   textdatei5
   textdatei6

Diese Funktion hier habe ich mir schon gebastelt:
[code lang=php]
function auflisten($eintrag)
{
 if (is_dir($eintrag))
 {
  echo $eintrag."/<br>";
  $verzeichnis = scandir($eintrag);

foreach ($verzeichnis as $neuer_eintrag)
  {
   if ($neuer_eintrag == "." || $neuer_eintrag == "..")
    continue;

auflisten($eintrag."/".$neuer_eintrag);
  }
 }
 else
 {
  echo $eintrag."<br>";
 }
}
[/php]

Sie gibt unformatiert mit Rekursion das ganze aus. Aber wie speicher ich das nun in einem Array ab anstatt es auszugeben?

Vielen dank für eure gute Hilfe!

  1. echo $begrüßung;

    [...] wie kann ich im assoziativen Array speichern, ob eine Datei oder ein Verzeichnis vorliegt.

    Eine Datei ist ein String, ein Verzeichnis ein Array. is_array() und !is_array() können zum Unterscheiden herangezogen werden.

    echo "$verabschiedung $name";

    1. echo $begrüßung;

      [...] wie kann ich im assoziativen Array speichern, ob eine Datei oder ein Verzeichnis vorliegt.

      Eine Datei ist ein String, ein Verzeichnis ein Array. is_array() und !is_array() können zum Unterscheiden herangezogen werden.

      Naja, aber wie baue ich denn nun in die Funktion ein, dass das ganze in einem Array (sagen wir mal $struktur) gespeichert werden sollte?
      Eigentlich müsste ich ja dafür einen weiteren Parameter erstellen, in dem gespeichert ist, an welcher Stelle im Array ich mich gerade befinde, damit ich an dieser Stelle abspeichern kann. Aber wie kann ich dynamisch auf die Xte Ebene eines Arrays zugreifen?

      1. Hi,

        Eigentlich müsste ich ja dafür einen weiteren Parameter erstellen, in dem gespeichert ist, an welcher Stelle im Array ich mich gerade befinde, damit ich an dieser Stelle abspeichern kann. Aber wie kann ich dynamisch auf die Xte Ebene eines Arrays zugreifen?

        Die x-te Ebene hat dich bei einem *rekursiven* Vorgehen doch gar nicht zu kuemmern - sondern immer nur die *aktuelle*.

        Wenn ein Verzeichnis vorliegt, dann lege es als Array-Element an, und weise ihm die Rueckgabe des (rekursiven) Funktionsaufrufes zu.

        Pseudocode:

        function lese_verzeichnis(...) {  
          $array = array();  
          while(Eintrag = readdir()) {  
            if(Eintrag == Verzeichnis) {  
              $array[] = lese_verzeichnis(Eintrag);  
            }  
            else {  
              $array[] = Eintrag;  
          }  
          return $array;  
        }
        

        MfG ChrisB

        --
        "The Internet: Technological marvel of marvels - but if you don't know *what* you're lookin' for on the Internet, it is nothing but a time-sucking vortex from hell."
        1. Hello,

          Pseudocode:

          function lese_verzeichnis(...) {

          $array = array();
            while(Eintrag = readdir()) {     ## an die Datei namens '0' denken, also auf === false prüfen
              if(Eintrag == Verzeichnis) {   ## versuche mal is_dir auf einem Linux-System, wenn es ein

          ## Link eist auf ein Directory

          $array[] = lese_verzeichnis(Eintrag);
              }
              else {
                $array[] = Eintrag;
            }
            return $array;
          }

            
          Dieses Beispiel kann durchaus ein Problem mit einer Endlosschliefe durch zirkulären Verlauf bekommen, wenn nämlich ein Link auf ein höheres Verzeichnis vorhanden ist.  
            
            
            
            
          Ein harzliches Glückauf  
            
          Tom vom Berg  
          ![](http://selfhtml.bitworks.de/Virencheck.gif)  
            
          
          -- 
          Nur selber lernen macht schlau  
          <http://bergpost.annerschbarrich.de>
          
        2. Hi,

          Eigentlich müsste ich ja dafür einen weiteren Parameter erstellen, in dem gespeichert ist, an welcher Stelle im Array ich mich gerade befinde, damit ich an dieser Stelle abspeichern kann. Aber wie kann ich dynamisch auf die Xte Ebene eines Arrays zugreifen?

          Die x-te Ebene hat dich bei einem *rekursiven* Vorgehen doch gar nicht zu kuemmern - sondern immer nur die *aktuelle*.

          Pseudocode:

          function lese_verzeichnis(...) {

          $array = array();
            while(Eintrag = readdir()) {
              if(Eintrag == Verzeichnis) {
                $array[] = lese_verzeichnis(Eintrag);
              }
              else {
                $array[] = Eintrag;
            }
            return $array;
          }

            
          Danke, irgendwie hatte ich eine Blockade. Das mit dem "file === 0" ist übrigens kein Problem, weil ich diese Verzeichnisbäume manuell erstelle und eine Datei mit 0 nicht vorkommen wird.  
          Noch eine letzte Frage: könnten Probleme auftreten, wenn ich folgendes mache?:  
            
          Pseudocode:  
            
          ~~~php
          function lese_verzeichnis(...) {  
            $array = array();  
            while(Eintrag = readdir()) {  
              if(Eintrag == Verzeichnis) {  
                $array[Eintrag] = lese_verzeichnis(Eintrag); # Index enthält nun Name des Verzeichnis  
              }  
              else {  
                $array[Eintrag] = 123; # Index enthält nun Name der Datei, der Inhalt (123) ist bedeutungslos  
            }  
            return $array;  
          }
          

          Das muss ich machen, damit mir nicht die Namen des Ordners verloren gehen, weil ein Ordner ja in diesem Falle ein Array ist und der Index nach ChrisBs Methode nur eine Zahl ist.

          1. Hi,

            Das mit dem "file === 0" ist übrigens kein Problem, weil ich diese Verzeichnisbäume manuell erstelle und eine Datei mit 0 nicht vorkommen wird.

            Aber . und .. kommen vor - und da haben wir schon das von Tom angesprochene Problem, wenn auch leicht anders, als er meinte.

            Noch eine letzte Frage: könnten Probleme auftreten, wenn ich folgendes mache?:

            $array[Eintrag] = lese_verzeichnis(Eintrag); # Index enthält nun Name des Verzeichnis
                }
                else {
                  $array[Eintrag] = 123; # Index enthält nun Name der Datei, der Inhalt (123) ist bedeutungslos

            Sollte eigentlich keine Probleme geben.
            Ein Datei-/Verzeichnisname ist ja pro Ebene eindeutig, und was assoziative Array-Indices angeht, ist PHP nicht sonderlich pingelig.

            MfG ChrisB

            --
            "The Internet: Technological marvel of marvels - but if you don't know *what* you're lookin' for on the Internet, it is nothing but a time-sucking vortex from hell."