Jörg: Multi-Dimensionales Array

Hallo.

Problem: Ich möchte Pfade und Dateien rekursiv und sortiert ausgeben.

Lösungsansatz:

<?php  
function scan_dir ($original_dir) {  
  
  if ($handle = opendir($original_dir)) {  
      while (false != ($dir = readdir($handle))) {  
          if (is_dir($original_dir.$dir) && $dir != '.' && $dir != '..') {  
            // $sort[$dir] = $dir;  
            // echo ' dir-'.$original_dir.$dir.' ';  
            scan_dir ($original_dir.$dir.'/');  
          }  
          elseif (is_file($original_dir.$dir)) {  
            // $sort_file[$dir] = $dir;  
            // echo ' File-'.$dir.' ';  
          }  
      }  
      closedir($handle);  
  }  
  
}  
/*  
ksort($sort_file);  
foreach ($sort_file as $dir) {  
  echo $dir . '<br />';  
}  
*/  
?>

Wenn ich die Echos ein-kommentiere, dann bekomme ich alles angezeigt aber nicht sortiert.
Ich denke mal, daß ich da ein Multi-Dimensionales Array brauche.
Wenn ja, wie macht man es dann? Syntax? Ausgabe?

MfG Jörg

  1. Hi,

    Problem: Ich möchte Pfade und Dateien rekursiv und sortiert ausgeben.

    Ich denke mal, daß ich da ein Multi-Dimensionales Array brauche.

    Nicht unbedingt - wenn du Pfad und Dateiname als ein Datum zusammenfassen möchtest, dann tut's auch eine Dimension.

    Wenn ja, wie macht man es dann? Syntax? Ausgabe?

    Das kommt erst mal drauf an, wie du das Array aufbauen möchtest.

    MfG ChrisB

    --
    Light travels faster than sound - that's why most people appear bright until you hear them speak.
  2. Hello,

    Problem: Ich möchte Pfade und Dateien rekursiv und sortiert ausgeben.

    Du solltest Dir erst diesen Thread durchlesen:
    http://forum.de.selfhtml.org/archiv/2007/12/t163759/#m1066530

    Sonst könntest Du in die Falle mit dem zyklischen Verlauf hineintapsen

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
    Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
  3. Hab da immer noch n Problem.
    Wie bekomme ich ein array aus einer funktion?
    Eigentlich sollte das doch so stimmen?

    <?php  
    function scan_dir ($dir) {  
      
      if ($handle = opendir($dir)) {  
          while (false !== ($res = readdir($handle))) {  
              if (is_dir($dir.$res) && $res != '.' && $res != '..') {  
                $res_d = $res;  
                $array_dir[$res_d] = $res_d;  
                // echo ' dir-'.$dir.$res.' ';  
                // scan_dir ($dir.$res.'/');  
              }  
              elseif (is_file($dir.$res)) {  
                $res_f = $res;  
                $array_file[$res_f] = $res_f;  
                // echo ' File-'.$res.' ';  
              }  
          }  
          closedir($handle);  
      }  
      ksort($array_dir);  
      ksort($array_file);  
      return array($array_dir,$array_file);  
    }  
    ?>
    
    <?php  
      include("./code/config/config.ini");  
      include("./code/include/scan_dir.icl");  
      
      scan_dir ($original_dir);  
      
      foreach ($array_dir as $key) {  
        echo ($array_dir);  
        echo '<br />';  
      }  
    ?>
    
    1. Hello,

      Hab da immer noch n Problem.
      Wie bekomme ich ein array aus einer funktion?

      return array($array_dir,$array_file);

      Das stimmt.
      Du brauchst Dann nur das Funktionsergebnis entgegen zu nehmen:

      $_dirlist = scan_dir ($original_dir);

      foreach ($_dirlist as $enty)
          {
              echo ($array_dir);
              echo '<br />';
          }

      In Deinem Code habe ich nochmal herumgespielt:

      <?php

      function scan_dir ($dir)
      {
          $dir = rtrim($dir, '/').'/';

      if (!$handle = opendir($dir)) return false;

      $_result['link']['name'] = array();
          $_result['dir']['name']  = array();
          $_result['file']['name'] = array();
          $_result['file']['size'] = array();

      $_index  = array();
          $_index['file'] = 0;

      while (false !== ($res = readdir($handle)))
          {
              if (is_dir($dir.$res) && is_link($dir.$res))
              {
                  $_result['link']['name'][] = $dir.$res;
              }
              elseif (is_dir($dir.$res) && $res != '.' && $res != '..')
              {
                  $_result['dir']['name'][] = $dir.$res;
              }
              elseif (is_file($dir.$res))
              {
                  $_index['file']++;
                  $_result['file']['name'][$_index['file']] = $dir.$res;
                  $_result['file']['size'][$_index['file']] = filesize($_result['file']['name'][$_index['file']]);
              }
          }

      closedir($handle);

      natsort($_result['link']['name']);
          natsort($_result['dir']['name']);
          natsort($_result['file']['name']);

      return array($_result);
      }

      #===================================================================================

      PHP main

      #===================================================================================

      $_dirlist = scan_dir ('../../.');

      echo "<pre>\r\n";
      echo htmlspecialchars(print_r($_dirlist,1));
      echo "</pre>\r\n";

      ?>

      Die Trennung von (DIR || LINK) und 'nur' DIR ist mMn wichtig, wenn Du später mit den Ergebnissen weiterarbeiten willst, um das Ganze vielleicht rekursiv abzuwickeln.

      Die Links darfst Du dann nicht ungeprüft rekursiv auflösen, sonst könnte sich Dein Programm aufhängen.

      Liebe Grüße aus dem schönen Oberharz

      Tom vom Berg

      --
      Nur selber lernen macht schlau
      http://bergpost.annerschbarrich.de
      1. Cool  ;-)

        Danke. Das sieht gut aus :)

        MfG Jörg

        1. Sorry, daß ich immer noch nerve....

          Aber ich bekomme das einfach nicht rekursiv....

          Wenn ich "echo $scan;" über "scan_dir ($scan);" eintrage bekomme ich alle Werte aber in das Array wird das nicht aufgenommen.
          Aus dem Array bekomme ich nur den Stamm-Pfad.

          Aktueller Stand:

          <?php  
          function scan_dir ($dir)  
          {  
              $dir = rtrim($dir, '/').'/';  
            
              if (!$handle = opendir($dir)) return false;  
            
              $_result['link']['name'] = array();  
              $_result['dir']['name']  = array();  
              $_result['file']['name'] = array();  
              $_result['file']['size'] = array();  
            
              $_index  = array();  
              $_index['file'] = 0;  
            
              while (false !== ($res = readdir($handle)))  
              {  
                  if (is_dir($dir.$res) && is_link($dir.$res))  
                  {  
                      $_result['link']['name'][] = $dir.$res;  
                  }  
                  elseif (is_dir($dir.$res) && $res != '.' && $res != '..')  
                  {  
                      $_result['dir']['name'][] = $dir.$res;  
                      $scan = rtrim($dir.$res, '/').'/';  
                      scan_dir ($scan);  
                  }  
                  elseif (is_file($dir.$res))  
                  {  
                      $_index['file']++;  
                      $_result['file']['name'][$_index['file']] = $dir.$res;  
                      $_result['file']['size'][$_index['file']] = filesize($_result['file']['name'][$_index['file']]);  
                  }  
              }  
            
              closedir($handle);  
            
              natsort($_result['link']['name']);  
              natsort($_result['dir']['name']);  
              natsort($_result['file']['name']);  
            
              return array($_result);  
          }  
          ?>  
            
          <?php  
            include("./code/config/config.ini");  
            include("./code/include/scan_dir.icl");  
            
            $_dirlist = scan_dir ($original_dir);  
            foreach ($_dirlist['0']['dir']['name'] as $array) {  
              echo $array;  
              echo '<br />';  
            }  
            
            echo "<pre>\r\n";  
            echo htmlspecialchars(print_r($_dirlist,1));  
            echo "</pre>\r\n";  
          ?>
          
          1. Hello,

            <?php

            include("./code/config/config.ini");
              include("./code/include/scan_dir.icl");

            $_dirlist = scan_dir ($original_dir);

            foreach ($_dirlist['dir']['name'] as $directory)

            {

            echo $directory;
                  echo '<br />';
              }

            Um das Ganze rekursiv zu machen, musst Du Dir erst einmal überlegen, wie Du die Directories dann zum Schluss speichern willst. Es empfiehlt sich, absolute Pfade einzutragen.

            /home/
               /home/user1/
               /home/user2/
               /home/user3/
               /home/user1/htdocs/
               /home/user1/data/
               /home/user1/logs/
               /home/user2/htdocs/
               /home/user2/data/
               /home/user2/logs/
               /home/user3/privat/briefe/
               /home/user3/htdocs/

            usw.

            Dazu müsstest DU einen kleinen chirurgischen Eingriff in die Funktion vornehmen:

            elseif (is_dir($dir.$res) && $res != '.' && $res != '..')
                    {
            #            $_result['dir']['name'][] = $dir.$res;
                        $_result['dir']['name'][] = realpath($dir.$res);
            #            $scan = rtrim($dir.$res, '/').'/';
            #            scan_dir ($scan);
                    }

            http://de2.php.net/manual/en/function.realpath.php

            Wenn Du das so machst, kannst Du Dir ein großes Sammelarray aufbauen:

            $_superdir = array();
               $_dirlist = scan_dir ($start_dir);  ## Startdir muss die Dir-Liste des letzten
                                                   ## Scanlaufs abarbeiten
               $_superdir = array_merge($_superdir, scan_dir['dir']['name']);

            Wenn Du aber nun überlegst, welche Teile der Scan-Funktion überhaupt rekursiv sein müssten, um den ganzen Diretory-Tree unterhalb eines Startpunktes einsammeln zu können, dann bleibt da erstmal nur der Typ DIR ohne LINK übrig.

            Es ist aber einfacher, die Sammelliste nicht wirklich durch die rekursive Funktion zu schleppen, sondern diese Funktion nur die Adresse der Liste mitschleppen zu lassen.

              
              
            <?php   ### get_dirtree.php ###  
              
            #---------------------------------------------------------------------------------  
            // $dir       Startverzeichnis, von dem aus der Directorybaum aufgelöst werden soll  
            // $dirtree   Adresse der Directory-Liste, die gefüllt werden soll  
            // $errors    Fehlerzähler, wird jeweils erhöht, wenn ein Directory nicht geöffnet  
            //            werden konnte  
            // RETURN     Fehler  
              
               function get_dirtree($dir, &$_dirtree, $errors=0)  
               {  
                  $dir = rtrim($dir, '/').'/';  
                  if (!$handle = opendir($dir)) return ++$errors;  
              
                  while (false !== ($res = readdir($handle)))  
                  {  
                      if (is_dir($dir.$res) && $res != '.' && $res != '..' &&  !is_link($dir.$res))  
                      {  
                          $_dirtree[] = realpath($dir.$res);  
                          $errors = get_dirtree($dir.$res, &$_dirtree, $errors);  
                      }  
                  }  
                  return $errors;  
               }  
              
            #-----------------------------------------------------------------------------------  
              
               $_dirtree = array();  
              
               $errors = get_dirtree('../../', $_dirtree);  
              
               echo "<pre>\r\n";  
               echo htmlspecialchars(print_r($_dirtree,1));  
               echo "<p><b>Fehler:</b> $errors</p>\r\n";  
               echo "</pre>\r\n";  
              
            ?>  
              
            
            

            Wenn Du auch die Verzeichnis-Links berücksichtigen willst, musst Du nur vorher prüfen, ob dieser schon in der Liste steht. Wenn ja, darfst Du kein zweites Mal in diese Ebene eintreten.

            Liebe Grüße aus dem schönen Oberharz

            Tom vom Berg

            --
            Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de