Ich möchte nur zur Kenntnis nehmen. Ich habe mehrere Dateien erstellt. Wenn während des Vorgangs ein Fehler auftritt, müssen die zuvor erstellten Dateien gelöscht werden. Beim Erstellen von Dateien, vergessen zu verwenden fclose($create_file);und beim Löschen, bekam Warning: unlink(created_file.xml): Permission denied in.... Um solche Fehler zu vermeiden, müssen die erstellten Dateien geschlossen werden.
Heutzutage stehen mindestens zwei Optionen zur Verfügung.
Löschen Sie vor dem Löschen des Ordners alle Dateien und Ordner (und dies bedeutet Rekursion!). Hier ist ein Beispiel:
publicstaticfunction deleteDir($dirPath){if(! is_dir($dirPath)){thrownewInvalidArgumentException("$dirPath must be a directory");}if(substr($dirPath, strlen($dirPath)-1,1)!='/'){
$dirPath .='/';}
$files = glob($dirPath .'*', GLOB_MARK);foreach($files as $file){if(is_dir($file)){self::deleteDir($file);}else{
unlink($file);}}
rmdir($dirPath);}
Und wenn Sie 5.2+ verwenden, können Sie einen RecursiveIterator verwenden, ohne die Rekursion selbst zu implementieren:
Ihre zweite Implementierung ist etwas gefährlich: Sie sucht nicht nach Punkten ( .und ..) und löscht den aufgelösten Pfad, nicht den tatsächlichen.
Alix Axel
9
kleines Add-On :-) glob () unterstützt keine Dateien wie .htaccess. Ich habe die Funktion verwendet, um Verzeichnisse zu löschen, die von KCFinder (CKEditor-Plugin) erstellt wurden und sowohl .htaccess als auch .thumbs (Datei + Ordner) generieren. Stattdessen habe ich die scandirFunktion verwendet, um die Ordnerliste zu erhalten. Stellen Sie einfach sicher, dass Sie das '.' und '..' Dateien aus der Ergebnisliste.
Joshua - Pendo
25
DIRECTORY_SEPARATOR ist nicht erforderlich, wenn Sie Pfade zum Senden an das Betriebssystem erstellen. Windows akzeptiert auch Schrägstriche. Es ist hauptsächlich nützlich, um explode()einen Pfad vom Betriebssystem aus zu finden. alanhogan.com/tips/php/directory-separator-not-necessary
ReactiveRaven
5
Zusätzlich zu @Alix Axel Die Verwendung von [SplFileInfo :: getRealPath ()] ( php.net/manual/en/splfileinfo.getrealpath.php ) ist hier keine gute Idee. Diese Methode erweitert alle symbolischen Links, dh es wird eine echte Datei von irgendwoher gelöscht, anstatt ein Symlink aus dem Zielverzeichnis. Sie sollten stattdessen SplFileInfo :: getPathname () verwenden.
Vijit
2
Ich stimme @Vijit zu, benutze getPathname () anstelle von getRealPath (). Es macht dasselbe, ohne mehr zu löschen, als Sie erwarten, wenn Symlinks gefunden werden.
JoeMoe1984
196
Ich benutze dies im Allgemeinen, um alle Dateien in einem Ordner zu löschen:
Dadurch werden Ordner nicht rekursiv gelöscht. Es funktioniert nur, wenn der Ordner nur reguläre Dateien enthält, die alle Dateierweiterungen haben.
mgnb
5
Wenn keine Rekursion erforderlich ist, ist dies die bisher beste und einfachste Antwort. Vielen Dank!
Eisbehr
2
Verwenden Sie glob folgendermaßen , um alle Dateien aus einem Ordner zu entfernen , nicht nur diejenigen mit Erweiterungen: Auf array_map('unlink', glob("$dirname/*"));diese Weise können Sie immer noch keine im Ordner verschachtelten Verzeichnisse löschen.
Kremuwa
Beachten Sie, dass dadurch auch (versteckte) Punktdateien entfernt werden.
BadHorsie
85
Was ist der einfachste Weg, ein Verzeichnis mit all seinen Dateien zu löschen?
Ich hoffe du meinst es nicht ernst. Was passiert, wenn $ dir /
The Pixel Developer
108
@Das gleiche wie bei jedem der oben genannten Codes. Ist es nicht?
Ihr gesunder Menschenverstand
7
Beachten Sie, dass Sie je $dirnach Generierung / Bereitstellung möglicherweise eine zusätzliche Vorverarbeitung durchführen müssen, um die Sicherheit zu gewährleisten und Fehler zu vermeiden. Wenn sich beispielsweise $direin nicht entkoppelter Raum oder ein Semikolon darin befindet, können unerwünschte Nebenwirkungen auftreten. Dies ist bei Antworten, die Dinge wie verwenden, nicht der Fall, rmdir()da sie die Sonderzeichen für Sie behandeln.
@ThePixelDeveloper Sie sollten sich keine Gedanken über das Löschen von / machen, dies würde nur funktionieren, wenn Sie das Skript in der Befehlszeile als root starten würden, da im Web alles als Apache-Benutzer geschieht
Ben
49
Kurze Funktion, die den Job macht:
function deleteDir($path){return is_file($path)?@unlink($path):
array_map(__FUNCTION__, glob($path.'/*'))==@rmdir($path);}
Mit großer Kraft geht eine große Verantwortung einher : Wenn Sie diese Funktion mit einem leeren Wert aufrufen, werden Dateien gelöscht, die mit root ( /) beginnen. Als Schutz können Sie überprüfen, ob der Pfad leer ist:
function deleteDir($path){if(empty($path)){returnfalse;}return is_file($path)?@unlink($path):
array_map(__FUNCTION__, glob($path.'/*'))==@rmdir($path);}
Die statische Funktion funktioniert nicht, weil $ this === NULL, wenn Sie eine statische Funktion für eine Klasse aufrufen. Es würde funktionieren, wenn$this_func = array(__CLASS__, __FUNCTION__);
Matt Connolly
2
Kann jemand die Zeile erklären array_map($class_func, glob($path.'/*')) == @rmdir($path)? Ich denke, er rekursiert durch die Unterordner, aber was macht der == @ rmdir-Teil? Wie gibt das <Array von Booleschen Werten> == <Boolescher Wert> die Antwort zurück? Prüft es, ob jeder Rückgabewert der Rekursion mit dem Booleschen Wert rechts übereinstimmt?
Arviman
2
Es ist ein Trick, zwei Anweisungen zu einer Anweisung zusammenzuführen. Dies liegt daran, dass ternäre Operatoren nur eine Anweisung pro Argument zulassen. array_map(...)Entfernt alle Dateien im Verzeichnis und @rmdir(...)das Verzeichnis selbst.
Blaise
3
Achtung! Diese Funktion prüft nicht, ob der Pfad wirklich existiert. Wenn Sie ein leeres Argument übergeben, beginnt die Funktion, Dateien ab dem Stammverzeichnis zu löschen! Fügen Sie Ihrem Pfad eine Überprüfung der Integrität hinzu, bevor Sie diese Funktion ausführen.
Tatu Ulmanen
3
Einige Leute haben Tatus Kommentar nicht gesehen und rekursiv gelöscht /, deshalb habe ich meinem Beitrag eine geschützte Version angehängt.
Blaise
22
Wie in den meisten Stimmen auf der PHP-Handbuchseite zu rmdir()(siehe http://php.net/manual/es/function.rmdir.php ) zu sehen ist, gibt die glob()Funktion keine versteckten Dateien zurück. scandir()wird als Alternative bereitgestellt, um dieses Problem zu lösen.
Der dort beschriebene Algorithmus (der in meinem Fall wie ein Zauber wirkte) ist:
<?php
function delTree($dir){
$files = array_diff(scandir($dir), array('.','..'));foreach($files as $file){(is_dir("$dir/$file"))? delTree("$dir/$file"): unlink("$dir/$file");}return rmdir($dir);}?>
Kannst du bitte erklären, dass is_dir ("$ dir / $ file") - nicht mit dem Parameter "$ dir / $ file" übereinstimmt
Igor L.
Was meinst du? Es wird geprüft, ob der in einem Verzeichnis ( $file) gefundene Eintrag ein Verzeichnis oder eine Datei ist. "$dir/$file"ist das gleiche wie $dir . "/" . $file.
Deutscher Latorre
Ich wusste ehrlich gesagt nicht, dass Sie Variablen wie diese verketten können :) thx
Igor L.
18
Dies ist eine kürzere Version, die für mich großartig funktioniert
Ich konnte jedoch einige komplexe Verzeichnisstrukturen mit dieser Methode nicht löschen. Versuchen Sie es daher zunächst, um sicherzustellen, dass sie ordnungsgemäß funktioniert.
Ich könnte diese Verzeichnisstruktur mit einer Windows-spezifischen Implementierung löschen:
$dir = strtr($dir,'/','\\');// quotes are important, otherwise one could// delete "foo" instead of "foo bar"
system('RMDIR /S /Q "'.$dir.'"');
Und der Vollständigkeit halber hier ein alter Code von mir:
function xrmdir($dir){
$items = scandir($dir);foreach($items as $item){if($item ==='.'|| $item ==='..'){continue;}
$path = $dir.'/'.$item;if(is_dir($path)){
xrmdir($path);}else{
unlink($path);}}
rmdir($dir);}
function my_folder_delete($path){if(!empty($path)&& is_dir($path)){
$dir =newRecursiveDirectoryIterator($path,RecursiveDirectoryIterator::SKIP_DOTS);//upper dirs are not included,otherwise DISASTER HAPPENS :)
$files =newRecursiveIteratorIterator($dir,RecursiveIteratorIterator::CHILD_FIRST);foreach($files as $f){if(is_file($f)){unlink($f);}else{$empty_dirs[]= $f;}}if(!empty($empty_dirs)){foreach($empty_dirs as $eachDir){rmdir($eachDir);}} rmdir($path);}}
ps ERINNERN SIE SICH! Übergeben Sie keine leeren Werte an Funktionen zum Löschen von Verzeichnissen !!! (Sichern Sie sie immer, sonst könnten Sie eines Tages DISASTER bekommen !!)
/*
* Remove the directory and its content (all files and subdirectories).
* @param string $dir the directory name
*/function rmrf($dir){foreach(glob($dir)as $file){if(is_dir($file)){
rmrf("$file/*");
rmdir($file);}else{
unlink($file);}}}
Ich bevorzuge dies, weil es immer noch TRUE zurückgibt, wenn es erfolgreich ist, und FALSE, wenn es fehlschlägt, und es verhindert auch einen Fehler, bei dem ein leerer Pfad versuchen könnte, alles aus '/ *' zu löschen !!:
function deleteDir($path){return!empty($path)&& is_file($path)?@unlink($path):(array_reduce(glob($path.'/*'),function($r, $i){return $r && deleteDir($i);}, TRUE))&&@rmdir($path);}
Ich möchte die Antwort von @alcuadrado mit dem Kommentar von @Vijit zum Umgang mit Symlinks erweitern. Verwenden Sie zunächst getRealPath (). Wenn Sie jedoch Symlinks haben, bei denen es sich um Ordner handelt, schlägt dies fehl, da versucht wird, rmdir für einen Link aufzurufen. Sie benötigen daher eine zusätzliche Überprüfung.
$it =newRecursiveDirectoryIterator($dir,RecursiveDirectoryIterator::SKIP_DOTS);
$files =newRecursiveIteratorIterator($it,RecursiveIteratorIterator::CHILD_FIRST);foreach($files as $file){if($file->isLink()){
unlink($file->getPathname());}elseif($file->isDir()){
rmdir($file->getPathname());}else{
unlink($file->getPathname());}}
rmdir($dir);
Kleine Änderung des Codes von Alcuadrado - globkeine Dateien mit Namen von Punkten wie z. .htaccessB. Scandir verwenden und Skript löscht sich selbst - überprüfen __FILE__.
function deleteDir($dirPath){if(!is_dir($dirPath)){thrownewInvalidArgumentException("$dirPath must be a directory");}if(substr($dirPath, strlen($dirPath)-1,1)!='/'){
$dirPath .='/';}
$files = scandir($dirPath);foreach($files as $file){if($file ==='.'|| $file ==='..')continue;if(is_dir($dirPath.$file)){
deleteDir($dirPath.$file);}else{if($dirPath.$file !== __FILE__){
unlink($dirPath.$file);}}}
rmdir($dirPath);}
Normalerweise füge ich vor dem Ausführen von rm -rf eine Überprüfung der Integrität von $ cache_folder hinzu, um kostspielige Fehler zu vermeiden
Glyphe
1
Alle Dateien im Ordner array_map('unlink', glob("$directory/*.*"));
löschen Alle array_map('unlink', array_diff(glob("$directory/.*),array("$directory/.","$directory/..")))
löschen . * - Dateien im Ordner (ohne: "." Und "..") Löschen Sie nun den Ordner selbst rmdir($directory)
2 Cent zu dieser Antwort oben hinzufügen , was übrigens großartig ist
Nachdem Ihre Glob-Funktion (oder eine ähnliche Funktion) das Verzeichnis gescannt / gelesen hat, fügen Sie eine Bedingung hinzu, um zu überprüfen, ob die Antwort nicht leer ist. invalid argument supplied for foreach()Andernfalls wird eine Warnung ausgegeben. So...
if(! empty( $files )){foreach( $files as $file ){// do your stuff here...}}
Meine volle Funktion (als Objektmethode):
privatefunction recursiveRemoveDirectory( $directory ){if(! is_dir( $directory )){thrownewInvalidArgumentException("$directory must be a directory");}if( substr( $directory, strlen( $directory )-1,1)!='/'){
$directory .='/';}
$files = glob( $directory ."*");if(! empty( $files )){foreach( $files as $file ){if( is_dir( $file )){
$this->recursiveRemoveDirectory( $file );}else{
unlink( $file );}}}
rmdir( $directory );}// END recursiveRemoveDirectory()
$ options (Array) - zum Entfernen des Verzeichnisses. Gültige Optionen sind: traverseSymlinks: boolean, ob auch Symlinks zu den Verzeichnissen durchlaufen werden sollen. Der Standardwert ist false, dass der Inhalt des verknüpften Verzeichnisses nicht gelöscht wird. In diesem Standardfall wird nur der Symlink entfernt.
Wie die Lösung von Playnox, jedoch mit dem eleganten integrierten DirectoryIterator:
function delete_directory($dirPath){if(is_dir($dirPath)){
$objects=newDirectoryIterator($dirPath);foreach($objects as $object){if(!$object->isDot()){if($object->isDir()){
delete_directory($object->getPathname());}else{
unlink($object->getPathname());}}}
rmdir($dirPath);}else{thrownewException(__FUNCTION__.'(dirPath): dirPath is not a directory!');}}
fclose($create_file);
und beim Löschen, bekamWarning: unlink(created_file.xml): Permission denied in...
. Um solche Fehler zu vermeiden, müssen die erstellten Dateien geschlossen werden.Antworten:
Heutzutage stehen mindestens zwei Optionen zur Verfügung.
Löschen Sie vor dem Löschen des Ordners alle Dateien und Ordner (und dies bedeutet Rekursion!). Hier ist ein Beispiel:
Und wenn Sie 5.2+ verwenden, können Sie einen RecursiveIterator verwenden, ohne die Rekursion selbst zu implementieren:
quelle
.
und..
) und löscht den aufgelösten Pfad, nicht den tatsächlichen.scandir
Funktion verwendet, um die Ordnerliste zu erhalten. Stellen Sie einfach sicher, dass Sie das '.' und '..' Dateien aus der Ergebnisliste.explode()
einen Pfad vom Betriebssystem aus zu finden. alanhogan.com/tips/php/directory-separator-not-necessaryIch benutze dies im Allgemeinen, um alle Dateien in einem Ordner zu löschen:
Und dann kannst du es tun
quelle
array_map('unlink', glob("$dirname/*"));
diese Weise können Sie immer noch keine im Ordner verschachtelten Verzeichnisse löschen.quelle
$dir
nach Generierung / Bereitstellung möglicherweise eine zusätzliche Vorverarbeitung durchführen müssen, um die Sicherheit zu gewährleisten und Fehler zu vermeiden. Wenn sich beispielsweise$dir
ein nicht entkoppelter Raum oder ein Semikolon darin befindet, können unerwünschte Nebenwirkungen auftreten. Dies ist bei Antworten, die Dinge wie verwenden, nicht der Fall,rmdir()
da sie die Sonderzeichen für Sie behandeln.system('rmdir '.escapeshellarg($path).' /s /q');
Kurze Funktion, die den Job macht:
Ich benutze es in einer Utils-Klasse wie dieser:
Mit großer Kraft geht eine große Verantwortung einher : Wenn Sie diese Funktion mit einem leeren Wert aufrufen, werden Dateien gelöscht, die mit root (
/
) beginnen. Als Schutz können Sie überprüfen, ob der Pfad leer ist:quelle
$this_func = array(__CLASS__, __FUNCTION__);
array_map($class_func, glob($path.'/*')) == @rmdir($path)
? Ich denke, er rekursiert durch die Unterordner, aber was macht der == @ rmdir-Teil? Wie gibt das <Array von Booleschen Werten> == <Boolescher Wert> die Antwort zurück? Prüft es, ob jeder Rückgabewert der Rekursion mit dem Booleschen Wert rechts übereinstimmt?array_map(...)
Entfernt alle Dateien im Verzeichnis und@rmdir(...)
das Verzeichnis selbst./
, deshalb habe ich meinem Beitrag eine geschützte Version angehängt.Wie in den meisten Stimmen auf der PHP-Handbuchseite zu
rmdir()
(siehe http://php.net/manual/es/function.rmdir.php ) zu sehen ist, gibt dieglob()
Funktion keine versteckten Dateien zurück.scandir()
wird als Alternative bereitgestellt, um dieses Problem zu lösen.Der dort beschriebene Algorithmus (der in meinem Fall wie ein Zauber wirkte) ist:
quelle
$file
) gefundene Eintrag ein Verzeichnis oder eine Datei ist."$dir/$file"
ist das gleiche wie$dir . "/" . $file
.Dies ist eine kürzere Version, die für mich großartig funktioniert
quelle
Sie können das Dateisystem ( Code ) von Symfony verwenden :
Ich konnte jedoch einige komplexe Verzeichnisstrukturen mit dieser Methode nicht löschen. Versuchen Sie es daher zunächst, um sicherzustellen, dass sie ordnungsgemäß funktioniert.
Ich könnte diese Verzeichnisstruktur mit einer Windows-spezifischen Implementierung löschen:
Und der Vollständigkeit halber hier ein alter Code von mir:
quelle
Hier haben Sie eine schöne und einfache Rekursion zum Löschen aller Dateien im Quellverzeichnis einschließlich dieses Verzeichnisses:
Die Funktion basiert auf einer Rekursion zum Kopieren des Verzeichnisses. Diese Funktion finden Sie hier: Kopieren Sie den gesamten Inhalt eines Verzeichnisses mit PHP in ein anderes
quelle
Die beste Lösung für mich
Code:
ps ERINNERN SIE SICH!
Übergeben Sie keine leeren Werte an Funktionen zum Löschen von Verzeichnissen !!! (Sichern Sie sie immer, sonst könnten Sie eines Tages DISASTER bekommen !!)
quelle
Was ist damit:
quelle
Die Glob-Funktion gibt die versteckten Dateien nicht zurück, daher kann scandir nützlicher sein, wenn Sie versuchen, einen Baum rekursiv zu löschen.
quelle
Sie können Folgendes versuchen:
quelle
Ich bevorzuge dies, weil es immer noch TRUE zurückgibt, wenn es erfolgreich ist, und FALSE, wenn es fehlschlägt, und es verhindert auch einen Fehler, bei dem ein leerer Pfad versuchen könnte, alles aus '/ *' zu löschen !!:
quelle
Ich möchte die Antwort von @alcuadrado mit dem Kommentar von @Vijit zum Umgang mit Symlinks erweitern. Verwenden Sie zunächst getRealPath (). Wenn Sie jedoch Symlinks haben, bei denen es sich um Ordner handelt, schlägt dies fehl, da versucht wird, rmdir für einen Link aufzurufen. Sie benötigen daher eine zusätzliche Überprüfung.
quelle
Verwenden von DirectoryIterator entspricht einer vorherigen Antwort…
quelle
Dieser funktioniert für mich:
quelle
Etwas wie das?
quelle
Kleine Änderung des Codes von Alcuadrado -
glob
keine Dateien mit Namen von Punkten wie z..htaccess
B. Scandir verwenden und Skript löscht sich selbst - überprüfen__FILE__
.quelle
Beispiel für den Linux-Server:
exec('rm -f -r ' . $cache_folder . '/*');
quelle
Alle Dateien im Ordner
array_map('unlink', glob("$directory/*.*"));
löschen Alle
array_map('unlink', array_diff(glob("$directory/.*),array("$directory/.","$directory/..")))
löschen . * - Dateien im Ordner (ohne: "." Und "..") Löschen Sie nun den Ordner selbst
rmdir($directory)
quelle
2 Cent zu dieser Antwort oben hinzufügen , was übrigens großartig ist
Nachdem Ihre Glob-Funktion (oder eine ähnliche Funktion) das Verzeichnis gescannt / gelesen hat, fügen Sie eine Bedingung hinzu, um zu überprüfen, ob die Antwort nicht leer ist.
invalid argument supplied for foreach()
Andernfalls wird eine Warnung ausgegeben. So...Meine volle Funktion (als Objektmethode):
quelle
Hier ist die Lösung, die perfekt funktioniert:
quelle
Sie könnten die YII-Helfer kopieren
$ directory (string) - wird rekursiv gelöscht.
$ options (Array) - zum Entfernen des Verzeichnisses. Gültige Optionen sind: traverseSymlinks: boolean, ob auch Symlinks zu den Verzeichnissen durchlaufen werden sollen. Der Standardwert ist
false
, dass der Inhalt des verknüpften Verzeichnisses nicht gelöscht wird. In diesem Standardfall wird nur der Symlink entfernt.quelle
Lassen Sie den obigen Code von php.net ausprobieren
Arbeite gut für mich
quelle
Für Windows:
quelle
Wie die Lösung von Playnox, jedoch mit dem eleganten integrierten DirectoryIterator:
quelle
Ich erinnere mich nicht, woher ich diese Funktion kopiert habe, aber es sieht so aus, als ob sie nicht aufgeführt ist und für mich funktioniert
quelle
Simpel und einfach...
quelle
Was ist damit?
Aktualisierung: https://paulund.co.uk/php-delete-directory-and-files-in-directory
quelle
Wenn Sie sich nicht sicher sind, ob der angegebene Pfad ein Verzeichnis oder eine Datei ist, können Sie mit dieser Funktion den Pfad löschen
quelle