php.de

Zurück   php.de > PHP.de Wiki

Kategorien

Verzeichnis auslesen

Aus PHP.de Wiki

Wechseln zu:Navigation, Suche

Bild:Icon-under-construction.png

Dieser Artikel befindet sich noch in der Bearbeitung.

Inhaltsverzeichnis

Hinweis

  • Der Übersichtlichkeit halber werden Kommentare des vorhergehenden Codes tw. weggelassen.
  • Die Beispielcodes machen Gebrauch von sogenanntem "linksgehaltenem Code". Es ist sinnvoll, sich vor der Lektüre mit diesem Ansatz vertraut zu machen.

Grundlage

$dir = '/path/to/files/';
 
// Verzeichnis öffnen
$handle = opendir($dir); 
 
// Auslesen bis readdir FALSE zurückgibt
while (false !== ($file = readdir($handle))) {
 
    // Verarbeitung des Dateinamens, Zuweisung o.ä.
    $file;
 
}
closedir($handle);

Erweiterung

  • Fehlerkontrolle (fehlendes oder nicht lesbares Verzeichnis)
  • Ausschluss der Dateieinträge . (Selbstreferenz) und .. (übergeordneter Ordner)
  • Ausschluss von Unterverzeichniseinträgen
$dir = '/path/to/files/';
 
if (false === is_dir($dir)) {
    // Fehlerverarbeitung
    // Abbruch
    die;
}
 
$handle = opendir($dir); 
 
if (false === $handle) {
    // Fehlerverarbeitung
    // Abbruch
    die;
}
 
while (false !== ($file = readdir($handle))) {
 
    // Ausschluss von . und ..
    if ('.' == $file || '..' == $file) {
        // nächstes Element
        continue;
    }
 
    // Ausschluss von Verzeichnisnamen
    if (is_dir($dir . $file)) {
        // nächstes Element
        continue;
    }
 
    // Verarbeitung des Dateinamens, Zuweisung o.ä.
    $file;
 
}
closedir($handle);

Hinweis

Hier und nachfolgend muß sichergestellt werden, dass $dir ein abschließendes / enthält. Grund ist die Kombination mit dem ausgelesenen Datenamen über $dir . $file. Dies kann bspw. durch dieses Codefragment sicher gestellt werden.

$dir = rtrim($dir , ' /\\') . '/';
 

Ebenfalls ist die Problematik verschiedener Pfadbegrenzen (/ bzw. \) zu berücksichtigen

Unterverzeichnisse rekursiv auslesen

Um im Leseordner auch die Einträge von Unterverzeichnissen zu berücksichtigen, wird ein Teil Funktionalität in eine selbstaufrufende Funktion ausgelagert.

function readDirRecursive($dir) 
{
    if (false === is_dir($dir)) {
        return false;
    }
 
    $handle = opendir($dir); 
 
    if (false === $handle) {
        return false;
    }
 
    while (false !== ($file = readdir($handle))) {
 
        // Ausschluss von . und ..
        if ('.' == $file || '..' == $file) {
            // nächstes Element
            continue;
        }
 
        // Verarbeitung von Verzeichnisnamen
        if (is_dir($dir . $file)) {
 
            // Selbstaufruf
            readDirRecursive($dir . $file . '/');
 
            // nächstes Element
            continue;
        }
 
        // Verarbeitung des Dateinamens, Zuweisung o.ä.
        $file;
 
    }
    closedir($handle);
 
return true;
}
 
 
$dir = '/path/to/files';
 
readDirRecursive($dir);

Verarbeitung der Inhalte

Bisher wurden die Dateinamen noch nicht weiter verarbeitet. Sollen die Dateinamen nicht direkt ausgegeben werden, sondern bspw. in ein Array eingehen, macht es uns die Funktionskapselung etwas schwieriger. Nachfolgend werden zwei Arten aufgeführt: Die Rückgabe via return und die Nutzung eines referentiellen Parameters.

Grundlage ist bei beiden Lösungen ein Sammeln der Dateinamen im Array $result. Dei Einträge werden dabei in Reihenfolge der Abarbeitung erstellt: Ein an der Leseposition gefundenes Unterverzeichnis wird zuerst durchlaufen (und ggf. weitere in ihm), bevor zur nächsten Position zurückgesprungen wird.

Array Return

Hier ist die Fehlerausgabe FALSE zu beachten, die im Anfang der Funktion erfolgen kann.

function readDirRecursive($dir) 
{
    if (false === is_dir($dir)) {
        return false;
    }
 
    $handle = opendir($dir); 
 
    if (false === $handle) {
        return false;
    }
 
    $result = array();
 
    while (false !== ($file = readdir($handle))) {
 
        // Ausschluss von . und ..
        if ('.' == $file || '..' == $file) {
            // nächstes Element
            continue;
        }
 
        // Verarbeitung von Verzeichnisnamen
        if (is_dir($dir . $file)) {
 
            // Selbstaufruf
            $resultSubdir = readDirRecursive($dir . $file . '/');
 
            // gültige Werte dem Rsultset hinzufügen
            if (false !== $resultSubdir) {
                $result = array_merge($result , $resultSubdir);
            }
 
            // nächstes Element
            continue;
        }
 
        // Array Zuweisung des Dateinamens
        $result[] = $file;
 
    }
    closedir($handle);
 
return $result;
}
 
 
$dir = '/path/to/files';
 
$result = readDirRecursive($dir);

Referenz-Aufruf

Der Vorteil dieser Funktion: Es muß nicht mit einer Zwischenmenge $resultSubdir gearbeitet werden, da der rekursive Aufruf direkt in die Ergebnismenge schreiben kann. Weiterhin bleibt der Rückgabewert der Funktion frei und könnte bspw. bei einem Verzeichnislesefehler ein entstehendes FALSE bis zum Ur-Aufruf "durchschleifen".

function readDirRecursive($dir , & $result) 
{
    if (false === is_dir($dir)) {
        return false;
    }
 
    $handle = opendir($dir); 
 
    if (false === $handle) {
        return false;
    }
 
    while (false !== ($file = readdir($handle))) {
 
        // Ausschluss von . und ..
        if ('.' == $file || '..' == $file) {
            // nächstes Element
            continue;
        }
 
        // Verarbeitung von Verzeichnisnamen
        if (is_dir($dir . $file)) {
 
            // Selbstaufruf
            readDirRecursive($dir . $file . '/' , $result);
 
            // nächstes Element
            continue;
        }
 
        // Array Zuweisung des Dateinamens
        $result[] = $file;
 
    }
    closedir($handle);
 
return true;
}
 
 
$dir = '/path/to/files';
 
$result = array();
readDirRecursive($dir , $result);

Anmerkungen

Verzeichnisprüfung

Da die Einträge . und .. in jedem normalen Verzeichnis vorhanden sind und stets als erste Einträge zurückgegeben werden, wird oft statt is_dir ($file) eine alternative Syntax gebraucht: Es werden zwei pauschale readdir ($handle); Aufrufe gestartet, deren Rückgabe nicht verarbeitet wird. Diese Aufrufe müssen natürlich vor der while Schleife erfolgen.

readdir Rückgabe

Das PHP Manual stellt ausdrücklich in seinem Beispiel die Verwendung von while (false !== ($file = readdir($handle))) als korrekt gegenüber while ($file = readdir($handle)) heraus.
Hintergrund: Nur die Identitätsprüfung (===) bzw. deren Negation nimmt eine explizite Typprüfung vor. Alle anderen Vergleiche unterscheiden faktisch nicht zwischen NULL, '' (leerer String), 0, '0' etc. Ein Dateiname namens "0" würde hier also bspw. zum Schleifenabbruch führen.

Analog sind die folgenden Schleifenbedingungen falsch:

while (false != ($file = readdir($handle)) {}
while (! false == ($file = readdir($handle)) {}

Verzeichnisse auslesen

Natürlich ist auch das Auslesen aller "Nicht-Dateien" (Verzeichnisse) möglich. Dabei kehren sich quasi die Bearbeitung der Zustände is_dir($file) und "restliche" um. Der Selbstaufruf muß natürlich weiterhin für Verzeichniseinträge erfolgen. Relevanter Schleifencode:

while (false !== ($file = readdir($handle))) {
 
    // Ausschluss von . und ..
    if ('.' == $file || '..' == $file) {
        // nächstes Element
        continue;
    }
 
    // Verarbeitung von Verzeichnisnamen
    if (is_dir($dir . $file)) {
 
        // Verarbeitung des Verzeichnisnamens, Zuweisung o.ä.
        $file;
 
        // Selbstaufruf
        readDirRecursive($dir . $file . '/');
    }
 
    // Else Fall: Für Dateien passiert nichts
}

Alle Zeitangaben in WEZ +2. Es ist jetzt 02:25 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Powered by vbWiki Pro 1.3 RC5. Copyright ©2006-2007, NuHit, LLC

Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum