dir()
PHP-Verzeichnisfunktionen: Verzeichnisse öffnen, lesen, erstellen und löschen mit opendir(), scandir(), mkdir() und DirectoryIterator.
Einführung
Dieses Kapitel behandelt die Arbeit mit Verzeichnissen in PHP: Öffnen, Lesen, Erstellen und Löschen sowie die inzwischen entfernte Funktion dir() und ihre modernen Alternativen. PHP liefert einen vollständigen Satz eingebauter Funktionen für diese Aufgaben, sodass Sie den Inhalt eines Ordners auflisten, einen Verzeichnisbaum durchlaufen oder temporäre Dateien bereinigen können, ohne auf das Betriebssystem zurückgreifen zu müssen.
Verzeichnisfunktionen werden am häufigsten benötigt, wenn Sie einen Upload-Manager erstellen, eine Dateiliste für eine Download-Seite generieren, temporäre Dateien bereinigen oder zur Laufzeit einen Ordner mit Templates oder Bildern durchsuchen.
Verzeichnisfunktionen in PHP verstehen
PHP gruppiert die Arbeit mit Verzeichnissen in eine Handvoll prozeduraler Funktionen sowie eine objektorientierte DirectoryIterator-Klasse. Die gebräuchlichsten sind:
opendir()— öffnet ein Verzeichnis und gibt ein Handle zurück (eine Ressource, aus der Sie lesen)readdir()— liest den nächsten Eintrag aus einem offenen Verzeichnis-Handleclosedir()— schließt ein Verzeichnis-Handle und gibt die Ressource freiscandir()— liest alle Einträge in einem einzigen Aufruf in ein arrayglob()— gibt Pfade zurück, die einem Shell-Wildcard-Muster entsprechenmkdir()— erstellt ein neues Verzeichnisrmdir()— löscht ein leeres Verzeichnisis_dir()— prüft, ob ein Pfad ein Verzeichnis ist
Jede Verzeichnisauflistung in PHP enthält die speziellen Einträge . (das Verzeichnis selbst) und .. (sein übergeordnetes Verzeichnis). Diese sollten Sie fast immer überspringen — das Vergessen ist eine häufige Fehlerquelle.
Verzeichnis mit opendir() und readdir() lesen
opendir() öffnet ein Verzeichnis und gibt ein Verzeichnis-Handle zurück. Dieses Handle übergeben Sie dann an readdir(), das bei jedem Aufruf den Namen des nächsten Eintrags zurückgibt und false, wenn keine weiteren Einträge vorhanden sind. Schließen Sie das Handle stets mit closedir(), wenn Sie fertig sind.
Da readdir() legitimerweise "0" zurückgeben kann (eine Datei, die tatsächlich 0 heißt), vergleichen Sie das Ergebnis mit !== false statt mit einer losen Prüfung, damit ein falscher Dateiname nicht als Ende der Liste fehlinterpretiert wird.
Beispiel von opendir() und readdir() in PHP
<?php
$dir = "/path/to/directory";
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
if ($file === "." || $file === "..") {
continue; // skip self and parent
}
echo "filename: " . $file . PHP_EOL;
}
closedir($dh);
}
}Für ein Verzeichnis mit a.txt, b.log und report.csv wird Folgendes ausgegeben:
filename: b.log
filename: report.csv
filename: a.txtDie Reihenfolge ist nicht alphabetisch — readdir() gibt Einträge in der Reihenfolge zurück, in der das Dateisystem sie speichert. Wenn Sie eine vorhersagbare Reihenfolge benötigen, verwenden Sie scandir() (das sortiert) oder sortieren Sie die Ergebnisse selbst.
Verzeichnis mit scandir() auf einmal auflisten
scandir() liest den gesamten Inhalt eines Verzeichnisses in einem einzigen Aufruf in ein array und sortiert das Ergebnis — im Gegensatz zu readdir() — standardmäßig alphabetisch. Dies ist der bequemste Weg, eine sortierte Dateiliste zu erhalten. Es enthält weiterhin . und .., die Sie herausfiltern müssen, wenn Sie nur echte Dateien möchten.
Verwendung der scandir()-Funktion in PHP
<?php
$dir = "/path/to/directory";
$files = scandir($dir);
print_r($files);Für ein Verzeichnis mit a.txt, b.log und report.csv ist die Ausgabe:
Array
(
[0] => .
[1] => ..
[2] => a.txt
[3] => b.log
[4] => report.csv
)Übergeben Sie SCANDIR_SORT_DESCENDING als drittes Argument, um die Reihenfolge umzukehren, oder SCANDIR_SORT_NONE, um die Sortierung zu überspringen (was bei sehr großen Verzeichnissen schneller ist).
Dateien mit glob() abgleichen
Wenn Sie nur Dateien wünschen, die einem Muster entsprechen — alle .txt-Dateien oder alles, das mit report beginnt — ist glob() die sauberste Option. Es akzeptiert ein Shell-Wildcard-Muster und gibt ein array mit übereinstimmenden Pfaden zurück:
<?php
foreach (glob("/path/to/directory/*.txt") as $file) {
echo $file . PHP_EOL;
}Wenn nur a.txt in unserem Beispielverzeichnis übereinstimmt, wird Folgendes ausgegeben:
/path/to/directory/a.txtIm Gegensatz zu scandir() schließt glob() weder . noch .. ein und gibt vollständige Pfade statt bloßer Dateinamen zurück.
Verzeichnisse mit mkdir() erstellen
Die Funktion mkdir() erstellt ein neues Verzeichnis. Das erste Argument ist der Pfad, das zweite setzt die Berechtigungen (ein oktaler Wert wie 0755), und das optionale dritte Argument erstellt, wenn es true ist, fehlende übergeordnete Verzeichnisse rekursiv.
Verwendung der mkdir()-Funktion in PHP
mkdir("/path/to/my/new/directory", 0755, true);Ohne das true-Flag schlägt mkdir() mit einer Warnung fehl, wenn ein übergeordnetes Verzeichnis noch nicht existiert. Auf Unix-ähnlichen Systemen werden die tatsächlichen Berechtigungen auch durch die Prozess-umask beeinflusst.
Verzeichnisse mit rmdir() löschen
Die Funktion rmdir() löscht ein Verzeichnis. Sie nimmt den Pfad des zu löschenden Verzeichnisses entgegen.
Verwendung der rmdir()-Funktion in PHP
rmdir("/path/to/my/new/directory");Hinweis: rmdir() entfernt nur leere Verzeichnisse. Um ein Verzeichnis zu löschen, das noch Dateien enthält, entfernen Sie zuerst die Dateien (und alle Unterverzeichnisse) — beispielsweise durch Durchlaufen des Inhalts mit scandir() und Aufruf von unlink() für jede Datei.
Die moderne Alternative: DirectoryIterator
Für objektorientieren Code ist die SPL-Klasse DirectoryIterator die empfohlene Methode zum Durchlaufen eines Verzeichnisses. Sie ist mit foreach iterierbar und liefert umfangreiche Informationen über jeden Eintrag — Name, Größe, Typ und Änderungszeit — ohne separate Funktionsaufrufe:
<?php
foreach (new DirectoryIterator("/path/to/directory") as $entry) {
if ($entry->isDot()) {
continue; // skip "." and ".."
}
echo $entry->getFilename() . PHP_EOL;
}Für ein Verzeichnis mit a.txt, b.log und report.csv wird Folgendes ausgegeben:
b.log
report.csv
a.txtisDot() überspringt praktischerweise sowohl . als auch .. in einer Prüfung. Um einen gesamten Verzeichnisbaum einschließlich Unterordner zu durchlaufen, verwenden Sie RecursiveDirectoryIterator zusammen mit RecursiveIteratorIterator.
Die veraltete dir()-Funktion
Veraltet: Die Funktion
dir()wurde in PHP 7.4 als veraltet markiert und in PHP 8.0 entfernt. Verwenden Sie stattdessenDirectoryIteratoroderscandir(). Das folgende Beispiel dient nur zur Pflege älteren Codes.
Die Funktion dir() gibt ein Directory-object zurück, das eine objektorientierte Möglichkeit bietet, Verzeichnisinhalte zu lesen. Im Gegensatz zu scandir(), das ein einfaches array zurückgibt, gibt dir() ein object mit Methoden wie read(), rewind() und close() zurück. Beachten Sie, dass dir() kein Alias für scandir() ist — sie dienen unterschiedlichen Zwecken und geben unterschiedliche Datentypen zurück.
Verwendung der dir()-Funktion in PHP (Legacy)
<?php
$dir = dir("/path/to/directory");
while (($file = $dir->read()) !== false) {
echo "filename: " . $file . PHP_EOL;
}
$dir->close();Fazit
PHP bietet mehrere Möglichkeiten zur Arbeit mit Verzeichnissen. Verwenden Sie scandir() oder glob() für schnelle, sortierte Auflistungen, das Trio opendir()/readdir()/closedir(), wenn Sie Einträge einzeln streamen möchten, und DirectoryIterator für sauberes objektorientiertes Durchlaufen. Erstellen und entfernen Sie Ordner mit mkdir() und rmdir(), und greifen Sie auf RecursiveDirectoryIterator zurück, wenn Sie in Unterverzeichnisse hinabsteigen müssen. Einen umfassenderen Überblick über die Arbeit mit dem Dateisystem finden Sie in den Kapiteln PHP Directory und PHP Filesystem.