DiamondDog: [PHP] Problem mit auflisten von Unterordnern

Hallo Leute, ich hab da ein kleines Problem und zwar listet mir das nachfolgende Script nur die Haupt nicht aber die darinliegenden Unterordner auf. Ich hoffe mir kann jemand sagen wie ich die Unterordner mit aufgelistet bekomme. Hier das Script:


<?php
$myfolder = $_SERVER['DOCUMENT_ROOT'].'/';

function list_folder($path){
  $folderList = array(); 
  
  if($handle = @opendir($path)){
    while (false !== ($file = readdir($handle))){
      if ($file != "." && $file != ".."){
	    if(is_dir($path."/".$file))
          $folderList[] = $path.$file;
      }
    }
  closedir($handle);
  }
  asort($folderList);
  return $folderList;
}


$folder_array = list_folder($myfolder);

foreach($folder_array AS $folder){
  echo $folder."<br>";
}
?>

Danke schon mal für eure Hilfe.

Mfg DiamondDog

akzeptierte Antworten

  1. Liebe Mitdenker, liebe Wissende, liebe Neugierige,

    ja? ja! Think positive!

    ich hab da ein kleines Problem und zwar listet mir das nachfolgende Script nur die Haupt nicht aber die darinliegenden Unterordner auf. Ich hoffe mir kann jemand sagen wie ich die Unterordner mit aufgelistet bekomme. Hier das Script:

    
    <?php
    $myfolder = $_SERVER['DOCUMENT_ROOT'].'/';
    
    function list_folder($path){
      $folderList = array(); 
      
      if($handle = @opendir($path)){
        while (false !== ($file = readdir($handle))){
          if ($file != "." && $file != ".."){
    	    if(is_dir($path."/".$file))  
    
          $folderList[] = __$path.$file__;  
    
      }
    }
    

    closedir($handle); } asort($folderList); return $folderList; }

    $folder_array = list_folder($myfolder);

    foreach($folder_array AS $folder){ echo $folder."<br>"; } ?>

    Die Funktion hat mindestens drei Fehler:

    • $path.$file sollte wohl $path.'/'.$file heißen?
    • das wäre aber trotzdem falsch, denn an diese Stelle gehört die Rekursion
    • und wenn das dann klappen würde, würde das Skript sich bei Links zurück
      zu einer höheren Ebeneaufhängen, also in eine Endlosschleife geraraten.

    Willst Du einen XPath ausgeben, oder den Dateibaum auch als (Array-)Baum abbilden?

    Spirituelle Grüße
    Euer Robert
    robert.r@online.de

    --
    Möge der wahre Forumsgeist ewig leben!
    1. Liebe Mitdenker, liebe Wissende, liebe Neugierige,

      ja? Leider nein!

      
      <?php
      $myfolder = $_SERVER['DOCUMENT_ROOT'].'/';
      
      function list_folder($path){
        $folderList = array(); 
        
        if($handle = @opendir($path)){
          while (false !== ($file = readdir($handle))){
            if ($file != "." && $file != ".."){
      	    if(is_dir($path."/".$file))  
      
            $folderList[] = __$path.$file__;  
      
        }
      }
      

      closedir($handle); } asort($folderList); return $folderList; }

      $folder_array = list_folder($myfolder);

      foreach($folder_array AS $folder){ echo $folder."<br>"; } ?>

      Das macht keinen Spaß mehr mit dieser merkwürdigen Eingabeverschandelungsfunktion. Kann man die nicht abschalten?

      Spirituelle Grüße
      Euer Robert
      robert.r@online.de

      --
      Möge der wahre Forumsgeist ewig leben!
      1. Tach!

        Das macht keinen Spaß mehr mit dieser merkwürdigen Eingabeverschandelungsfunktion. Kann man die nicht abschalten?

        Wenn du das Zitat meinst und es nicht verschandelt haben möchtest, dann lass es doch unberührt. Kommentare kaputtmachen ging übrigens auch im alten Forum hervorragend.

        dedlfix.

    2. Liebe Mitdenker, liebe Wissende, liebe Neugierige,

      ja! -> Link:

      Eine kurze Suche im Archiv nach "category:PHP dirlist" ergab den obenstenden Thread, der für dich interessant sein dürfte.

      Ich erinnere mich noch gut daran, dass ich nach dieser Diskussion unsere ganzen Projekte überarbeiten musste, weil wir nun endlich wussten, warum manche Skripte immer ins Timeaout liefen. Dedlfix und Tom sei Dank :-O

      Spirituelle Grüße
      Euer Robert
      robert.r@online.de

      --
      Möge der wahre Forumsgeist ewig leben!
  2. Moin!

    <?php
    # Dein Code ist nicht gut aufgeräumt, ich habe das mal geändert.
    $myfolder = '/var/www'; # Hier statisch, weil in der Konsole getestet.
    
    # So wie Du das anfängst brauchst Du eine globale Variable für den Array:
    $GLOBALS['folder_array']=array(); 
    list_folder($myfolder);
    asort($GLOBALS['folder_array']);
    foreach($GLOBALS['folder_array'] AS $folder){
      echo $folder."<br>\n";
    }
    exit; # "Deklaratorisch", damit der Progger weiß, hier ist das Hauptprogramm zu Ende
    
    
    function list_folder($path){
      if( $handle = @opendir($path) ) { 
      #Hinweis 
      #@ ist "böse", Du bekommst nicht mit, wenn ein Verzeichnis nicht lesbar ist
        while (false !== ($file = readdir($handle))){
          if ($file != "." && $file != ".." && is_dir($path."/".$file) ) {
            $GLOBALS['folder_array'][] = $path.'/'.$file;
            list_folder($path.'/'.$file); # das hier nennt sich "rekursiver Funktionsaufruf"
          }
        }
      closedir($handle);
      }
    }
    ?>
    

    Allerdings solltest Du noch links ausschließen:

    …
    if ($file != "." && $file != ".." && ! is_link($path."/".$file) && is_dir($path."/".$file) ) {
    …
    

    Jörg Reinholz

    1. Liebe Mitdenker, liebe Wissende, liebe Neugierige,

      ja!

      <?php
      # Dein Code ist nicht gut aufgeräumt, ich habe das mal geändert.
      $myfolder = '/var/www'; # Hier statisch, weil in der Konsole getestet.
      
      # So wie Du das anfängst brauchst Du eine globale Variable für den Array:
      $GLOBALS['folder_array']=array(); 
      list_folder($myfolder);
      asort($GLOBALS['folder_array']);
      foreach($GLOBALS['folder_array'] AS $folder){
        echo $folder."<br>\n";
      }
      exit; # "Deklaratorisch", damit der Progger weiß, hier ist das Hauptprogramm zu Ende
      
      
      function list_folder($path){
        if( $handle = @opendir($path) ) { 
        #Hinweis 
        #@ ist "böse", Du bekommst nicht mit, wenn ein Verzeichnis nicht lesbar ist
          while (false !== ($file = readdir($handle))){
      
          if ($file != "." && $file != ".." && is_dir($path."/".$file) ) {
      
          $GLOBALS['folder_array'][] = $path.'/'.$file;
          list_folder($path.'/'.$file); # das hier nennt sich "rekursiver Funktionsaufruf"
        }
      }
      

      closedir($handle); } } ?>

      Allerdings solltest Du noch links ausschließen:
      
      

      … if ($file != "." && $file != ".." && ! is_link($path."/".$file) && is_dir($path."/".$file) ) { …

      Es fehlt immer noch die Vermeidung eines zyklischen Verlaufs, wenn dir ein Link oder SymbolicLink ist.

      Huch? Jetzt sthet es plötzlich drin? Welche geheimen Kräfte wirken denn da wieder im Hintergrund?

      Spirituelle Grüße
      Euer Robert
      robert.r@online.de

      --
      Möge der wahre Forumsgeist ewig leben!
      1. Moin!

        Das Eingeben ist hier so "schwierig", um den Benutzern eine gewisse Sorgfalt anzugewöhnen.

        Jörg Reinholz

        1. Liebe Mitdenker, liebe Wissende, liebe Neugierige,

          ja!

          Das Eingeben ist hier so "schwierig", um den Benutzern eine gewisse Sorgfalt anzugewöhnen.

          Und dazu gehört auch, dass man das Archiv nicht mehr vernünftig lesen kann, dass man im Quelltext keine Markierungen mehr anbringen kann, usw.?

          Das Archiv ist der Wissensschatz des Forums. Wenn das wegen dieser Spielereien verloren ginge, wären 15 Jahre Arbeit von hunderten von Postern dahin.

          Spirituelle Grüße
          Euer Robert
          robert.r@online.de

          --
          Möge der wahre Forumsgeist ewig leben!
          1. Moin!

            Und dazu gehört auch, dass man das Archiv nicht mehr vernünftig lesen kann, dass man im Quelltext keine Markierungen mehr anbringen kann, usw.?

            Wie Matthias schon schrieb ging das Forum online, weil im Testforum zu wenig getestet wurde. Was gebraucht wird sind vernünftige Fehlermeldungen, wenigstens Links zum fehlerhaft wiedergegeben Beitrag.

            Bitte setze die Diskussion an dieser Stelle (im meta-Forum) und mit dieser Prämisse fort.

            Jörg Reinholz

    2. Moin!

      <?php
      # Dein Code ist nicht gut aufgeräumt, ich habe das mal geändert.
      $myfolder = '/var/www'; # Hier statisch, weil in der Konsole getestet.
      
      # So wie Du das anfängst brauchst Du eine globale Variable für den Array:
      $GLOBALS['folder_array']=array(); 
      list_folder($myfolder);
      asort($GLOBALS['folder_array']);
      foreach($GLOBALS['folder_array'] AS $folder){
        echo $folder."<br>\n";
      }
      exit; # "Deklaratorisch", damit der Progger weiß, hier ist das Hauptprogramm zu Ende
      
      
      function list_folder($path){
        if( $handle = @opendir($path) ) { 
        #Hinweis 
        #@ ist "böse", Du bekommst nicht mit, wenn ein Verzeichnis nicht lesbar ist
          while (false !== ($file = readdir($handle))){
            if ($file != "." && $file != ".." && is_dir($path."/".$file) ) {
              $GLOBALS['folder_array'][] = $path.'/'.$file;
              list_folder($path.'/'.$file); # das hier nennt sich "rekursiver Funktionsaufruf"
            }
          }
        closedir($handle);
        }
      }
      ?>
      

      Allerdings solltest Du noch links ausschließen:

      …
      if ($file != "." && $file != ".." && ! is_link($path."/".$file) && is_dir($path."/".$file) ) {
      …
      

      Jörg Reinholz

      Top das hat mir genau das gebracht was ich gesucht habe. Hab auch die Links mit ausgeschlossen ;-) Kurz am Rande, brauche das ganze um zu Prüfen ob in jedem Ordner eine index vorhanden ist und wenn nicht um dann dort dann eine zu erstellen, so das kein Ordner ohne eine index Datei ist. Das ganze mach ich auch nur, weil auf meine Seite massive At­ta­cke statt finden.

      Danke euch sehr für eure Hilfe.

      1. Moin!

        Das ganze mach ich auch nur, weil auf meine Seite massive At­ta­cke statt finden.

        Ah. Das erklärt die Panik, die aus dem Code ersichtlich wurde. Aber es stellt sich die Frage, warum Du Die Datei dann nicht automatisch anlegst (Code unten).

        Jörg Reinholz

        <?php
        # Dein Code ist nicht gut aufgeräumt, ich habe das mal geändert.
        $myfolder = '/var/www'; # Hier statisch, weil in der Konsole getestet.
        
        # So wie Du das anfängst brauchst Du eine globale Variable für den Array:
        $GLOBALS['folder_array']=array(); 
        list_folder($myfolder);
        asort($GLOBALS['folder_array']);
        foreach($GLOBALS['folder_array'] AS $folder){
          echo $folder."<br>\n";
          if (! (
                  is_file($folder.'/index.php') 
                  || is_file($folder.'/index.html') 
                  || is_file($folder.'/index.pl')
              )
          ) {
              if ( touch ($folder.'/index.html') ) {
                chmod ($folder.'/index.html', 0644)
                echo "Verzeichnis hatte keine index-Datei, wurde angelegt.<br>\n";
              } else {
                echo "Verzeichnis hatte keine index-Datei, Anlegen ging auch nicht.<br>\n";      
              }
          }
        }  
        exit; # "Deklaratorisch", damit der Progger weiß, hier ist das Hauptprogramm zu Ende
        
        
        function list_folder($path){
          if( $handle = @opendir($path) ) { 
          #Hinweis 
          #@ ist "böse", Du bekommst nicht mit, wenn ein Verzeichnis nicht lesbar ist
            while (false !== ($file = readdir($handle))){
              if ($file != "." && $file != ".." && is_dir($path."/".$file) ) {
                $GLOBALS['folder_array'][] = $path.'/'.$file;
                list_folder($path.'/'.$file); # das hier nennt sich "rekursiver Funktionsaufruf"
              }
            }
          closedir($handle);
          }
        }
        ?>
        
        1. Moin!

          Das ganze mach ich auch nur, weil auf meine Seite massive At­ta­cke statt finden.

          Ah. Das erklärt die Panik, die aus dem Code ersichtlich wurde. Aber es stellt sich die Frage, warum Du Die Datei dann nicht automatisch anlegst (Code unten).

          Jörg Reinholz

          <?php
          # Dein Code ist nicht gut aufgeräumt, ich habe das mal geändert.
          $myfolder = '/var/www'; # Hier statisch, weil in der Konsole getestet.
          
          # So wie Du das anfängst brauchst Du eine globale Variable für den Array:
          $GLOBALS['folder_array']=array(); 
          list_folder($myfolder);
          asort($GLOBALS['folder_array']);
          foreach($GLOBALS['folder_array'] AS $folder){
            echo $folder."<br>\n";
            if (! (
                    is_file($folder.'/index.php') 
                    || is_file($folder.'/index.html') 
                    || is_file($folder.'/index.pl')
                )
            ) {
                if ( touch ($folder.'/index.html') ) {
                  chmod ($folder.'/index.html', 0644)
                  echo "Verzeichnis hatte keine index-Datei, wurde angelegt.<br>\n";
                } else {
                  echo "Verzeichnis hatte keine index-Datei, Anlegen ging auch nicht.<br>\n";      
                }
            }
          }  
          exit; # "Deklaratorisch", damit der Progger weiß, hier ist das Hauptprogramm zu Ende
          
          
          function list_folder($path){
            if( $handle = @opendir($path) ) { 
            #Hinweis 
            #@ ist "böse", Du bekommst nicht mit, wenn ein Verzeichnis nicht lesbar ist
              while (false !== ($file = readdir($handle))){
                if ($file != "." && $file != ".." && is_dir($path."/".$file) ) {
                  $GLOBALS['folder_array'][] = $path.'/'.$file;
                  list_folder($path.'/'.$file); # das hier nennt sich "rekursiver Funktionsaufruf"
                }
              }
            closedir($handle);
            }
          }
          ?>
          

          Hab das ganze mal etwas erweitert und hoffe das das so ok ist, damit die erzeugte Datei auch Inhalt hat, habe ich folgendes hinzugefügt:

           if ( touch ($folder.'/index.html') ) {
                  chmod ($folder.'/index.html', 0644);
                  $datei = fopen($folder.'/index.html',"r+");
          	$inhalt = fgets($datei, 10);
          	if($inhalt == '') {
                    $inhalt = '<html><body bgcolor="#FFFFFF"></body></html>';
                  }
          	rewind($datei);
          	fwrite($datei, $inhalt);
                  fclose($datei);
                  echo "Verzeichnis hatte keine index-Datei, wurde angelegt.<br>\n";  
          		
                } else {
                  echo "Verzeichnis hatte keine index-Datei, Anlegen ging auch nicht.<br>\n";      
                }
          

          Sollte ich das schreiben in die Datei auch noch extra prüfen?

          PS: Hinter chmod fehlte ;

          1. Moin!

             if ( touch ($folder.'/index.html') ) {
                    chmod ($folder.'/index.html', 0644);
                    $datei = fopen($folder.'/index.html',"r+");
            	$inhalt = fgets($datei, 10);
            	if($inhalt == '') {
                      $inhalt = '<html><body bgcolor="#FFFFFF"></body></html>';
                    }
            	rewind($datei);
            	fwrite($datei, $inhalt);
                    fclose($datei);
            

            Sollte ich das schreiben in die Datei auch noch extra prüfen?

            Viel zu viel. Wenn Du eine Datei gerde eben erzeugt hast, dann wäre es fast ein Wunder, wenn Du nicht hineinschreiben kannst. Du kannst aber erzeugen und hineinschreiben zusammenfassen:

              #if ( touch ($folder.'/index.html') ) {
              if ( false === file_put_contents ($folder.'/index.html', '<h1>Ha!</h1><p>Nichts zu sehen?</p>') ) {
                echo "Verzeichnis hatte keine index-Datei, Anlegen ging auch nicht.<br>\n";
              } else {
                echo "Verzeichnis hatte keine index-Datei, wurde angelegt.<br>\n"; 
              }
            

            Jörg Reinholz

            1. Viel zu viel. Wenn Du eine Datei gerde eben erzeugt hast, dann wäre es fast ein Wunder, wenn Du nicht hineinschreiben kannst. Du kannst aber erzeugen und hineinschreiben zusammenfassen:

                #if ( touch ($folder.'/index.html') ) {
                if ( false === file_put_contents ($folder.'/index.html', '<h1>Ha!</h1><p>Nichts zu sehen?</p>') ) {
                  echo "Verzeichnis hatte keine index-Datei, Anlegen ging auch nicht.<br>\n";
                } else {
                  echo "Verzeichnis hatte keine index-Datei, wurde angelegt.<br>\n"; 
                }
              

              Jörg Reinholz

              Ok dann sollte ich doch noch einwenig mehr lesen damit meine Codes kürzer werden, hier noch mal die ganze schleife:

              foreach($GLOBALS['folder_array'] AS $folder){
                echo $folder."<br>\n";
                if (! (
                        is_file($folder.'/index.php') 
                        || is_file($folder.'/index.html') 
                        || is_file($folder.'/index.pl')
                    )
                ) {
                    if ( touch ($folder.'/index.html') ) {
                    	 if ( false === file_put_contents ($folder.'/index.html', '<html><body bgcolor="#FFFFFF"></body></html>') ) {
                      	 echo "Verzeichnis hatte keine index-Datei, wurde angelegt.<br>\n";
                    	 } else {
                      	echo "Verzeichnis hatte keine index-Datei, Anlegen ging auch nicht.<br>\n";      
                    	 }
                    }
              		
                }
              }  
              

              Das

              chmod ($folder.'/index.html', 0644);
              

              wegfällt war ja richtig oder? Da die Datei ja jetzt neu erzeugt und beschrieben wird... richtig?

              1. Moin!

                Das

                chmod ($folder.'/index.html', 0644);
                

                wegfällt war ja richtig oder? Da die Datei ja jetzt neu erzeugt und beschrieben wird... richtig?

                Das kommt darauf an, was Du willst und wie das System konfiguriert ist. Normalerweise sind vom Apache angelegte Dateien auch von jedem lesbar und werden deshalb beim Abruf auch ausgeliefert. Ist die index.html nicht lesbar gibt es eben einen 403er. In Deinem Fall: Was solls?

                Noch was Zu deinem Inhalt: Wenn es sich um eine Abwehrmaßnahme handelt, warum schreibst Du dann unnötig viel Zeug in die index.html - das ja auch wieder ausgeliefert werden muss. Und wofür braucht die einen Hintergrund, wenn dann doch gar nichts drin steht?

                Jörg Reinholz

              2. Kann es sein das mit der Stelle etwas nicht stimmt:

                if ( false === file_put_contents ($folder.'/index.html', '<html><body bgcolor="#FFFFFF"></body></html>') ) {
                  echo "Verzeichnis hatte keine index-Datei, wurde angelegt.<br>\n";
                } else {
                  echo "Verzeichnis hatte keine index-Datei, Anlegen ging auch nicht.<br>\n";      
                }
                

                Hab das Script gerade mal getestet , aber immer wenn eine Index erzeugt wird steht dort als Meldung: "Verzeichnis hatte keine index-Datei, Anlegen ging auch nicht."

                Aber die Index wurde ja erzeugt....?? verwiert

                1. Hallo DiamondDog,

                  Hab das Script gerade mal getestet , aber immer wenn eine Index erzeugt wird steht dort als Meldung: "Verzeichnis hatte keine index-Datei, Anlegen ging auch nicht."

                  Aber die Index wurde ja erzeugt....?? verwiert

                  Ne, verviert. ;-)

                  Bis demnächst
                  Matthias

                  --
                  Signaturen sind bloed (Steel) und Markdown ist mächtig.
                  1. Hallo DiamondDog,

                    Hab das Script gerade mal getestet , aber immer wenn eine Index erzeugt wird steht dort als Meldung: "Verzeichnis hatte keine index-Datei, Anlegen ging auch nicht."

                    Aber die Index wurde ja erzeugt....?? verwiert

                    Ne, verviert. ;-)

                    Bis demnächst
                    Matthias

                    --
                    Hm... aber wieso sagt das Script dann, das das anlegen nicht ging owohl es eine Datei angelegt hat? Es müste doch dann der Text: "Verzeichnis hatte keine index-Datei, wurde angelegt" dort stehen wenn die Datei erstellt wurde. > Signaturen sind bloed (Steel) und Markdown ist mächtig.

                    Hm... aber wieso sagt das Script dann, das das anlegen nicht ging owohl es eine Datei angelegt hat? Es müste doch dann der Text: "Verzeichnis hatte keine index-Datei, wurde angelegt" dort stehen wenn die Datei erstellt wurde.

                    Signaturen sind bloed (Steel) und Markdown ist mächtig.

                2. Moin!

                  Hab das Script gerade mal getestet , aber immer wenn eine Index erzeugt wird steht dort als Meldung: "Verzeichnis hatte keine index-Datei, Anlegen ging auch nicht."

                  Und? Kann es sein, dass Du GAR NICHT weißt, was Du tust?

                  if ( false === file_put_contents ($folder.'/index.html', '<html><body bgcolor="#FFFFFF"></body></html>') ) {
                    #echo "Verzeichnis hatte keine index-Datei, wurde angelegt.<br>\n";
                    echo "Verzeichnis hatte keine index-Datei, Anlegen ging auch nicht.<br>\n";      
                  } else {
                    #echo "Verzeichnis hatte keine index-Datei, Anlegen ging auch nicht.<br>\n";      
                    echo "Verzeichnis hatte keine index-Datei, wurde angelegt.<br>\n";
                  }
                  

                  Da müssen also lediglich zwei Zeilen vertauscht werden. Das nächste mal schreibe ich was ins Forum, was mir das Guthaben der Konten des Anwenders überweist und alle Passwörter sendet.

                  Jörg Reinholz

  3. Tach!

    Wenn man nach „php directory recursive“, bekommt man ein paar Seiten vom PHP-Handbuch als Ergebnis. In den Nutzerkommentaren findet man dann auch Lösungen, für solche uralten Probleme. Man muss da nicht nochmal das Rad neu erfinden. Und die sind dann auch schön kurz, beispielsweise weil PHP eingebaute Directory-Iteratoren hat.

    dedlfix.