Alle Dateien mit PHP aus einem Ordner löschen?

306

Zum Beispiel hatte ich einen Ordner namens "Temp" und wollte alle Dateien aus diesem Ordner mit PHP löschen oder leeren. Könnte ich das machen?

Flucht
quelle
14
Es ist gut, dass diese Frage unten beantwortet wurde, bevor sie als Duplikat markiert wurde. Die Antworten unten sind viel besser als die verknüpfte beantwortete Frage. Plus die Frage ist anders, diese Frage fordert, ein Verzeichnis zu leeren, nicht zu löschen.
Bart Burg
1
Ja, das ist eine andere Frage, die unterschiedliche Antworten gezogen hat. Es sollte nicht als Duplikat markiert werden.
Daniel Bingham

Antworten:

639
$files = glob('path/to/temp/*'); // get all file names
foreach($files as $file){ // iterate files
  if(is_file($file))
    unlink($file); // delete file
}

Wenn Sie "versteckte" Dateien wie .htaccess entfernen möchten, müssen Sie verwenden

$files = glob('path/to/temp/{,.}*', GLOB_BRACE);
Floern
quelle
4
Es gibt auch DirectoryIterator oder DirectoryRecursiveIterator.
Eugene
6
Obwohl es offensichtlich ist, würde ich erwähnen, dass zum Beispiel 'path / to / temp / *. Txt' nur txt-Dateien entfernt und so weiter.
Tertium
Funktioniert dies auch für relative Pfade? Angenommen, der vollständige Pfad lautet "/ var / www / html / folder_and_files_to_delete /". Das Löschskript befindet sich in "/var/www/html/delete_folders_and_files.php". Kann ich einfach "folder_and_files_to_delete" als Pfad verwenden?
Yoano
1
@yoano ja sicher, solange der relative Pfad korrekt ist.
Floern
Kann glob verwendet werden, wenn das Verzeichnis Zehntausende oder Hunderttausende von Dateien enthält?
Dave Heq
260

Wenn Sie wollen , dass alles aus dem Ordner löschen (einschließlich Unterordner) verwendet diese Kombination aus array_map, unlinkund glob:

array_map( 'unlink', array_filter((array) glob("path/to/temp/*") ) );

Dieser Aufruf kann auch leere Verzeichnisse verarbeiten (danke für den Tipp, @mojuba!)

Stichoza
quelle
33
Beste Antwort, danke. Um Hinweise zu vermeiden, würde ich auch glob("...") ?: [](PHP 5.4+) tun, da für ein leeres Verzeichnis glob()zurückgegeben wird false.
Mojuba
14
Es löscht alle Dateien im aktuellen Ordner, gibt jedoch eine Warnung für Unterordner zurück und löscht sie nicht.
Key-Six
2
Kombinieren der Antworten von Stichoza und Mojuba:array_map('unlink', ( glob( "path/to/temp/*" ) ? glob( "path/to/temp/*" ) : array() ) );
Ewout
7
@Ewout: Auch wenn wir Stichozas und Moujubas Antwort kombinieren, während Ihr Geben die gleiche Warnung für Unterordner zurückgibt und sie nicht löscht
Sulthan Allaudeen
3
Leider werden dadurch keine Unterordner gelöscht.
Tmarois
92

Hier ist ein moderner Ansatz unter Verwendung der Standard PHP Library (SPL) .

$dir = "path/to/directory";
$di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
$ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
foreach ( $ri as $file ) {
    $file->isDir() ?  rmdir($file) : unlink($file);
}
return true;
Yamiko
quelle
1
Dies funktioniert gut, wenn Sie keinen SSH-Zugriff haben und FTP buchstäblich Stunden benötigt , um viele Dateien und Ordner rekursiv zu löschen. Mit diesen Zeilen habe ich 35000 Dateien in weniger als 3 Sekunden gelöscht!
Guari
Für PHP 7.1-Benutzer muss $ file-> getRealPath () anstelle von $ file verwendet werden. Andernfalls erhalten Sie von PHP die Fehlermeldung, dass für die Aufhebung der Verknüpfung ein Pfad und keine Instanz von SplFileInfo erforderlich ist.
KeineMaster
68
foreach (new DirectoryIterator('/path/to/directory') as $fileInfo) {
    if(!$fileInfo->isDot()) {
        unlink($fileInfo->getPathname());
    }
}
JakeParis
quelle
es sollte die Verknüpfung aufheben ('/ path / to / directory /'.$ fileInfo-> getFilename ()); da unlink den pfad einnimmt. Gute Antwort.
Vic
8
Sie können sogar die Verknüpfung aufheben ($ fileInfo-> getPathname ()); Das würde Ihnen den vollständigen Pfad zur Datei geben. php.net/manual/en/directoryiterator.getpathname.php
Josh Holloway
Wird "DirectoryIterator" nicht auch über Unterverzeichnisse iteriert? In diesem Fall würde "Verknüpfung aufheben" in solchen Fällen eine Warnung auslösen. Sollte der Körper der Schleife nicht eher wie in Yamikos Antwort aussehen und jeden Eintrag überprüfen, ob es sich um eine Datei handelt, bevor Sie "Unlink" aufrufen?
Andreas Linnert
19

Dieser Code von http://php.net/unlink :

/**
 * Delete a file or recursively delete a directory
 *
 * @param string $str Path to file or directory
 */
function recursiveDelete($str) {
    if (is_file($str)) {
        return @unlink($str);
    }
    elseif (is_dir($str)) {
        $scan = glob(rtrim($str,'/').'/*');
        foreach($scan as $index=>$path) {
            recursiveDelete($path);
        }
        return @rmdir($str);
    }
}
Poelinca Dorin
quelle
16
$dir = 'your/directory/';
foreach(glob($dir.'*.*') as $v){
    unlink($v);
}
Haim Evgi
quelle
11

Siehe readdir und unlink .

<?php
    if ($handle = opendir('/path/to/files'))
    {
        echo "Directory handle: $handle\n";
        echo "Files:\n";

        while (false !== ($file = readdir($handle)))
        {
            if( is_file($file) )
            {
                unlink($file);
            }
        }
        closedir($handle);
    }
?>
StampedeXV
quelle
10

Angenommen, Sie haben einen Ordner mit VIELEN Dateien, die alle lesen und dann in zwei Schritten löschen, ist nicht so leistungsfähig. Ich glaube, die leistungsstärkste Methode zum Löschen von Dateien ist die Verwendung eines Systembefehls.

Zum Beispiel unter Linux benutze ich:

exec('rm -f '. $absolutePathToFolder .'*');

Oder dies, wenn Sie eine rekursive Löschung wünschen, ohne eine rekursive Funktion schreiben zu müssen

exec('rm -f -r '. $absolutePathToFolder .'*');

Die gleichen genauen Befehle existieren für jedes von PHP unterstützte Betriebssystem. Beachten Sie, dass dies eine DURCHFÜHRENDE Methode zum Löschen von Dateien ist. $ absolutePathToFolder MUSS überprüft und gesichert werden, bevor dieser Code ausgeführt wird, und Berechtigungen müssen erteilt werden.

Dario Corno
quelle
2
Etwas unsicher mit dieser Methode, wenn $absolutePatToFolderjemals leer ist
Lawrence Cherone
@LawrenceCherone Sind andere Alternativen sicherer?
Robsch
3
@LawrenceCherone Ich hoffe, dass heutzutage niemand PHP mit Root-Berechtigungen ausführt. Im Ernst, ich erwarte, dass die Eingabe "sicher" ist, da alle oben genannten Funktionen.
Dario Corno
Die am häufigsten gewählten Lösungen funktionieren nicht in Entwicklungsumgebungen, in denen www oder www-data nicht der Eigentümer ist. Es ist Sache des Serveradministrators, sicherzustellen, dass die richtigen Rechte für den Ordner festgelegt sind. exec ist ein unschätzbares Werkzeug, um Dinge zu erledigen, und mit großer Kraft usw. stackoverflow.com/a/2765171/418974
Christian Bonato
@LawrenceCherone Sie sind völlig richtig. Meine Antwort war für eine ganz bestimmte Situation gedacht, nur aus Leistungsgründen. Meine Antwort wurde gemäß Ihren Notizen geändert.
Dario Corno
4

Eine andere Lösung: Diese Klasse löscht alle Dateien, Unterverzeichnisse und Dateien in den Unterverzeichnissen.

class Your_Class_Name {
    /**
     * @see http://php.net/manual/de/function.array-map.php
     * @see http://www.php.net/manual/en/function.rmdir.php 
     * @see http://www.php.net/manual/en/function.glob.php
     * @see http://php.net/manual/de/function.unlink.php
     * @param string $path
     */
    public function delete($path) {
        if (is_dir($path)) {
            array_map(function($value) {
                $this->delete($value);
                rmdir($value);
            },glob($path . '/*', GLOB_ONLYDIR));
            array_map('unlink', glob($path."/*"));
        }
    }
}
Tommy
quelle
4

Die Funktion unlinkr löscht rekursiv alle Ordner und Dateien im angegebenen Pfad, indem sichergestellt wird, dass das Skript selbst nicht gelöscht wird.

function unlinkr($dir, $pattern = "*") {
    // find all files and folders matching pattern
    $files = glob($dir . "/$pattern"); 

    //interate thorugh the files and folders
    foreach($files as $file){ 
    //if it is a directory then re-call unlinkr function to delete files inside this directory     
        if (is_dir($file) and !in_array($file, array('..', '.')))  {
            echo "<p>opening directory $file </p>";
            unlinkr($file, $pattern);
            //remove the directory itself
            echo "<p> deleting directory $file </p>";
            rmdir($file);
        } else if(is_file($file) and ($file != __FILE__)) {
            // make sure you don't delete the current script
            echo "<p>deleting file $file </p>";
            unlink($file); 
        }
    }
}

Wenn Sie alle Dateien und Ordner löschen möchten, in denen Sie dieses Skript ablegen, rufen Sie es wie folgt auf

//get current working directory
$dir = getcwd();
unlinkr($dir);

Wenn Sie nur PHP-Dateien löschen möchten, rufen Sie es wie folgt auf

unlinkr($dir, "*.php");

Sie können auch einen anderen Pfad verwenden, um die Dateien zu löschen

unlinkr("/home/user/temp");

Dadurch werden alle Dateien im Verzeichnis home / user / temp gelöscht.

Tofeeq
quelle
3

Es wurde eine universelle Datei- und Ordnerbehandlungsklasse zum Kopieren, Verschieben, Löschen, Berechnen der Größe usw. veröffentlicht, die eine einzelne Datei oder eine Reihe von Ordnern verarbeiten kann.

https://gist.github.com/4689551

Benutzen:

So kopieren (oder verschieben) Sie eine einzelne Datei oder eine Reihe von Ordnern / Dateien:

$files = new Files();
$results = $files->copyOrMove('source/folder/optional-file', 'target/path', 'target-file-name-for-single-file.only', 'copy');

Löschen Sie eine einzelne Datei oder alle Dateien und Ordner in einem Pfad:

$files = new Files();
$results = $files->delete('source/folder/optional-file.name');

Berechnen Sie die Größe einer einzelnen Datei oder einer Reihe von Dateien in einer Reihe von Ordnern:

$files = new Files();
$results = $files->calculateSize('source/folder/optional-file.name');
AmyStephen
quelle
1
 <?
//delete all files from folder  & sub folders
function listFolderFiles($dir)
{
    $ffs = scandir($dir);
    echo '<ol>';
    foreach ($ffs as $ff) {
        if ($ff != '.' && $ff != '..') {
            if (file_exists("$dir/$ff")) {
                unlink("$dir/$ff");
            }
            echo '<li>' . $ff;
            if (is_dir($dir . '/' . $ff)) {
                listFolderFiles($dir . '/' . $ff);
            }
            echo '</li>';
        }
    }
    echo '</ol>';
}
$arr = array(
    "folder1",
    "folder2"
);
for ($x = 0; $x < count($arr); $x++) {
    $mm = $arr[$x];
    listFolderFiles($mm);
}
//end
?> 
user5579724
quelle
1

Für mich war die Lösung mit readdiram besten und wirkte wie ein Zauber. Mit globschlug die Funktion in einigen Szenarien fehl.

// Remove a directory recursively
function removeDirectory($dirPath) {
    if (! is_dir($dirPath)) {
        return false;
    }

    if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
        $dirPath .= '/';
    }

    if ($handle = opendir($dirPath)) {

        while (false !== ($sub = readdir($handle))) {
            if ($sub != "." && $sub != ".." && $sub != "Thumb.db") {
                $file = $dirPath . $sub;

                if (is_dir($file)) {
                    removeDirectory($file);
                } else {
                    unlink($file);
                }
            }
        }

        closedir($handle);
    }

    rmdir($dirPath);
}
Tiago Silva Pereira
quelle
0

Ich habe die Antwort von @Stichoza aktualisiert, um Dateien über Unterordner zu entfernen.

function glob_recursive($pattern, $flags = 0) {
    $fileList = glob($pattern, $flags);
    foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) {
        $subPattern = $dir.'/'.basename($pattern);
        $subFileList = glob_recursive($subPattern, $flags);
        $fileList = array_merge($fileList, $subFileList);
    }
    return $fileList;
}

function glob_recursive_unlink($pattern, $flags = 0) {
    array_map('unlink', glob_recursive($pattern, $flags));
}
tzi
quelle
0
public static function recursiveDelete($dir)
{
    foreach (new \DirectoryIterator($dir) as $fileInfo) {
        if (!$fileInfo->isDot()) {
            if ($fileInfo->isDir()) {
                recursiveDelete($fileInfo->getPathname());
            } else {
                unlink($fileInfo->getPathname());
            }
        }
    }
    rmdir($dir);
}
Mehmet
quelle
0

Es gibt ein Paket namens "Pusheh". Mit ihm können Sie ein Verzeichnis löschen oder ein Verzeichnis vollständig entfernen ( Github-Link ). Es ist auch auf Packagist erhältlich .

Wenn Sie beispielsweise das TempVerzeichnis löschen möchten , können Sie Folgendes tun:

Pusheh::clearDir("Temp");

// Or you can remove the directory completely
Pusheh::removeDirRecursively("Temp");

Wenn Sie interessiert sind, besuchen Sie das Wiki .

MAChitgarha
quelle