Chcę tylko zauważyć. Utworzyłem wiele plików i jeśli podczas tego procesu pojawi się błąd, to muszę usunąć wcześniej utworzone pliki. Po utworzeniu plików zapomniałem użyć, fclose($create_file);a po usunięciu dostałem Warning: unlink(created_file.xml): Permission denied in.... Aby uniknąć takich błędów, należy zamknąć utworzone pliki.
Przed usunięciem folderu usuń wszystkie jego pliki i foldery (a to oznacza rekurencję!). Oto przykład:
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);}
A jeśli używasz wersji 5.2+, możesz użyć RecursiveIterator, aby to zrobić bez samodzielnego wdrażania rekursji:
Druga implementacja jest nieco niebezpieczna: nie sprawdza kropek ( .i ..) i usuwa rozwiązaną ścieżkę, a nie rzeczywistą.
Alix Axel
9
mały dodatek :-) glob () nie obsługuje plików takich jak .htaccess. Użyłem tej funkcji do wyczyszczenia katalogów utworzonych przez KCFinder (wtyczka CKEditor), która generuje zarówno .htaccess, jak i .thumbs (plik + folder). Zamiast tego użyłem tej scandirfunkcji, aby uzyskać listę folderów. Upewnij się tylko, że filtrujesz „.” i pliki „..” z listy wyników.
Joshua - Pendo
25
DIRECTORY_SEPARATOR nie jest konieczny, gdy budujesz ścieżki do wysłania do systemu operacyjnego. Windows akceptuje również ukośniki. Jest to głównie przydatne do explode()wprowadzania ścieżki pobranej z systemu operacyjnego. alanhogan.com/tips/php/directory-separator-not-necessary
ReactiveRaven
5
Oprócz @Alix Axel Użycie tutaj [SplFileInfo :: getRealPath ()] ( php.net/manual/en/splfileinfo.getrealpath.php ) nie jest dobrym pomysłem. Ta metoda rozszerza wszystkie dowiązania symboliczne, co oznacza, że zostanie usunięty gdzieś prawdziwy plik zamiast dowiązania symbolicznego z katalogu docelowego. Zamiast tego powinieneś użyć SplFileInfo :: getPathname ().
Vijit,
2
Zgadzam się z @Vijit, używam getPathname () zamiast getRealPath (). Robi to samo, nie usuwając więcej niż oczekujesz, jeśli zostaną znalezione dowiązania symboliczne.
JoeMoe1984
196
Zwykle używam tego do usuwania wszystkich plików w folderze:
Nie powoduje to rekurencyjnego usuwania folderów; działa tylko wtedy, gdy folder zawiera tylko zwykłe pliki, z których wszystkie mają rozszerzenia plików.
mgnb
5
Jeśli nie jest wymagana rekurencja, jest to najlepsza i najprostsza jak dotąd odpowiedź. Dzięki!
eisbehr
2
Aby usunąć wszystkie pliki z folderu, nie tylko te z rozszerzeniami, użyj glob w następujący sposób: array_map('unlink', glob("$dirname/*"));To wciąż nie pozwala na usunięcie katalogów zagnieżdżonych w folderze.
kremuwa
Pamiętaj, że spowoduje to również usunięcie plików (ukrytych).
BadHorsie,
84
jaki jest najprostszy sposób na usunięcie katalogu zawierającego wszystkie pliki?
Mam nadzieję, że nie mówisz poważnie. Co się stanie, jeśli $ dir jest /
The Pixel Developer
108
@ Dokładnie tak samo, jak w przypadku każdego z powyższych kodów. Czyż nie
Twój zdrowy rozsądek,
7
Pamiętaj, że w zależności od sposobu $dirgenerowania / udostępniania może być konieczne wykonanie dodatkowego przetwarzania wstępnego, aby zachować bezpieczeństwo i uniknąć błędów. Na przykład, jeśli $dirmoże mieć nieskalowaną przestrzeń lub średnik, mogą wystąpić niepożądane skutki uboczne. Nie jest tak w przypadku odpowiedzi, które używają takich rzeczy, rmdir()ponieważ będą one obsługiwać znaki specjalne dla Ciebie.
Trott,
5
Wersja systemu Windows:system('rmdir '.escapeshellarg($path).' /s /q');
Cypher
2
@ThePixelDeveloper nie powinieneś martwić się usunięciem /, to zadziałałoby tylko, gdybyś odsunął skrypt w linii poleceń jako root, ponieważ w sieci wszystko dzieje się jako użytkownik apache
Ben
49
Krótka funkcja, która wykonuje zadanie:
function deleteDir($path){return is_file($path)?@unlink($path):
array_map(__FUNCTION__, glob($path.'/*'))==@rmdir($path);}
Z wielką mocą wiąże się wielka odpowiedzialność : wywołanie tej funkcji pustą wartością spowoduje usunięcie plików zaczynających się w root ( /). Jako zabezpieczenie możesz sprawdzić, czy ścieżka jest pusta:
function deleteDir($path){if(empty($path)){returnfalse;}return is_file($path)?@unlink($path):
array_map(__FUNCTION__, glob($path.'/*'))==@rmdir($path);}
Statyczny nie działa, ponieważ $ this === NULL, gdy wywołujesz funkcję statyczną w klasie. To by działało, gdyby$this_func = array(__CLASS__, __FUNCTION__);
Matt Connolly
2
Czy ktoś może wyjaśnić linię array_map($class_func, glob($path.'/*')) == @rmdir($path)? Chyba rekurencyjnie przegląda podfoldery, ale co robi część == @rmdir? W jaki sposób <tablica boolanów> == <boolean> zwraca odpowiedź? Czy sprawdza, czy każda zwracana wartość rekurencji jest taka sama jak wartość logiczna po prawej stronie?
arviman
2
Sztuczka polega na połączeniu dwóch instrukcji w jedną instrukcję. Wynika to z faktu, że operatory trójskładnikowe dopuszczają tylko jedną instrukcję na argument. array_map(...)usuwa wszystkie pliki w katalogu, @rmdir(...)usuwa sam katalog.
Blaise
3
Bądź ostrożny! Ta funkcja nie sprawdza, czy ścieżka naprawdę istnieje. Jeśli podasz pusty argument, funkcja zacznie usuwać pliki zaczynając od katalogu głównego! Przed uruchomieniem tej funkcji dodaj kontrolę poczytalności do swojej ścieżki.
Tatu Ulmanen
3
Niektóre osoby nie widziały komentarza Tatu i rekursywnie były usuwane /, więc dołączyłem do mojego posta zabezpieczoną wersję.
Blaise
22
Jak widać w najczęściej głosowanych komentarzach na stronie podręcznika PHP o rmdir()(patrz http://php.net/manual/es/function.rmdir.php ), glob()funkcja nie zwraca ukrytych plików. scandir()stanowi alternatywę, która rozwiązuje ten problem.
Opisany tam algorytm (który w moim przypadku działał jak urok) to:
<?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);}?>
Jednak nie mogłem usunąć niektórych złożonych struktur katalogów za pomocą tej metody, więc najpierw powinieneś spróbować, aby upewnić się, że działa poprawnie.
Mógłbym usunąć wspomnianą strukturę katalogów za pomocą implementacji specyficznej dla systemu Windows:
$dir = strtr($dir,'/','\\');// quotes are important, otherwise one could// delete "foo" instead of "foo bar"
system('RMDIR /S /Q "'.$dir.'"');
I tylko dla kompletności, oto mój stary kod:
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 PAMIĘTAJ! nie przekazuj PUSTEJ WARTOŚCI do żadnych funkcji usuwania katalogu !!! (zawsze wykonuj kopie zapasowe, w przeciwnym razie pewnego dnia możesz dostać katastrofę !!)
/*
* 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);}}}
Wolę to, ponieważ nadal zwraca PRAWDA, gdy się powiedzie, i FAŁSZ, gdy się nie powiedzie, a także zapobiega błędowi, w którym pusta ścieżka może próbować usunąć wszystko z „/ *” !!:
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);}
Chcę rozwinąć odpowiedź autorstwa @alcuadrado z komentarzem @Vijit dotyczącym obsługi dowiązań symbolicznych. Po pierwsze, użyj getRealPath (). Ale jeśli masz jakieś dowiązania symboliczne, które są folderami, to się nie powiedzie, ponieważ spróbuje wywołać rmdir na link - więc potrzebujesz dodatkowej kontroli.
$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);
Mała modyfikacja kodu alcuadrado - globnie widzę plików o nazwach z punktów takich jak, .htaccesswięc używam skandiru, a skrypt usuwa się sam - sprawdź __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);}
Zwykle lubię dodawać kontrolę poprawności do $ cache_folder przed uruchomieniem rm -rf, aby uniknąć kosztownych błędów
glif
1
Usuń wszystkie pliki w folderze array_map('unlink', glob("$directory/*.*"));
Usuń wszystko. * - Pliki w folderze (bez: „.” I „..”) array_map('unlink', array_diff(glob("$directory/.*),array("$directory/.","$directory/..")))
Teraz usuń sam folder rmdir($directory)
2 centy, aby dodać do tej odpowiedzi powyższej , co jest świetne BTW
Po zeskanowaniu / przeczytaniu katalogu przez funkcję glob (lub podobną) dodaj warunek, aby sprawdzić, czy odpowiedź nie jest pusta lub zostanie invalid argument supplied for foreach()wyświetlone ostrzeżenie. Więc...
if(! empty( $files )){foreach( $files as $file ){// do your stuff here...}}
Moja pełna funkcja (jako metoda obiektowa):
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) - do usunięcia katalogu. Prawidłowe opcje to: traverseSymlinks: boolean, czy dowiązania symboliczne do katalogów również powinny być przechodzące. Domyślnie falseoznacza to, że zawartość dowiązania symbolicznego nie zostanie usunięta. W takim przypadku domyślnym zostanie usunięte tylko dowiązanie symboliczne.
Podobnie jak rozwiązanie Playnox, ale z eleganckim wbudowanym 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);
a po usunięciu dostałemWarning: unlink(created_file.xml): Permission denied in...
. Aby uniknąć takich błędów, należy zamknąć utworzone pliki.Odpowiedzi:
Obecnie dostępne są co najmniej dwie opcje.
Przed usunięciem folderu usuń wszystkie jego pliki i foldery (a to oznacza rekurencję!). Oto przykład:
A jeśli używasz wersji 5.2+, możesz użyć RecursiveIterator, aby to zrobić bez samodzielnego wdrażania rekursji:
źródło
.
i..
) i usuwa rozwiązaną ścieżkę, a nie rzeczywistą.scandir
funkcji, aby uzyskać listę folderów. Upewnij się tylko, że filtrujesz „.” i pliki „..” z listy wyników.explode()
wprowadzania ścieżki pobranej z systemu operacyjnego. alanhogan.com/tips/php/directory-separator-not-necessaryZwykle używam tego do usuwania wszystkich plików w folderze:
I wtedy możesz zrobić
źródło
array_map('unlink', glob("$dirname/*"));
To wciąż nie pozwala na usunięcie katalogów zagnieżdżonych w folderze.źródło
$dir
generowania / udostępniania może być konieczne wykonanie dodatkowego przetwarzania wstępnego, aby zachować bezpieczeństwo i uniknąć błędów. Na przykład, jeśli$dir
może mieć nieskalowaną przestrzeń lub średnik, mogą wystąpić niepożądane skutki uboczne. Nie jest tak w przypadku odpowiedzi, które używają takich rzeczy,rmdir()
ponieważ będą one obsługiwać znaki specjalne dla Ciebie.system('rmdir '.escapeshellarg($path).' /s /q');
Krótka funkcja, która wykonuje zadanie:
Używam go w klasie Utils, takiej jak ta:
Z wielką mocą wiąże się wielka odpowiedzialność : wywołanie tej funkcji pustą wartością spowoduje usunięcie plików zaczynających się w root (
/
). Jako zabezpieczenie możesz sprawdzić, czy ścieżka jest pusta:źródło
$this_func = array(__CLASS__, __FUNCTION__);
array_map($class_func, glob($path.'/*')) == @rmdir($path)
? Chyba rekurencyjnie przegląda podfoldery, ale co robi część == @rmdir? W jaki sposób <tablica boolanów> == <boolean> zwraca odpowiedź? Czy sprawdza, czy każda zwracana wartość rekurencji jest taka sama jak wartość logiczna po prawej stronie?array_map(...)
usuwa wszystkie pliki w katalogu,@rmdir(...)
usuwa sam katalog./
, więc dołączyłem do mojego posta zabezpieczoną wersję.Jak widać w najczęściej głosowanych komentarzach na stronie podręcznika PHP o
rmdir()
(patrz http://php.net/manual/es/function.rmdir.php ),glob()
funkcja nie zwraca ukrytych plików.scandir()
stanowi alternatywę, która rozwiązuje ten problem.Opisany tam algorytm (który w moim przypadku działał jak urok) to:
źródło
$file
) jest katalogiem lub plikiem."$dir/$file"
jest taki sam jak$dir . "/" . $file
.To krótsza wersja działa dla mnie świetnie
źródło
Możesz użyć systemu plików Symfony ( kod ):
Jednak nie mogłem usunąć niektórych złożonych struktur katalogów za pomocą tej metody, więc najpierw powinieneś spróbować, aby upewnić się, że działa poprawnie.
Mógłbym usunąć wspomnianą strukturę katalogów za pomocą implementacji specyficznej dla systemu Windows:
I tylko dla kompletności, oto mój stary kod:
źródło
Oto jedna przyjemna i prosta rekursja do usunięcia wszystkich plików w katalogu źródłowym, w tym katalogu:
Funkcja opiera się na rekursji wykonanej dla kopiowania katalogu. Możesz znaleźć tę funkcję tutaj: Skopiuj całą zawartość katalogu do innego za pomocą php
źródło
Najlepsze rozwiązanie dla mnie
kod:
ps PAMIĘTAJ!
nie przekazuj PUSTEJ WARTOŚCI do żadnych funkcji usuwania katalogu !!! (zawsze wykonuj kopie zapasowe, w przeciwnym razie pewnego dnia możesz dostać katastrofę !!)
źródło
A co z tym:
źródło
Funkcja Glob nie zwraca ukrytych plików, dlatego scandir może być bardziej przydatny podczas próby rekurencyjnego usunięcia drzewa.
źródło
Możesz spróbować wykonać następujące czynności:
źródło
Wolę to, ponieważ nadal zwraca PRAWDA, gdy się powiedzie, i FAŁSZ, gdy się nie powiedzie, a także zapobiega błędowi, w którym pusta ścieżka może próbować usunąć wszystko z „/ *” !!:
źródło
Chcę rozwinąć odpowiedź autorstwa @alcuadrado z komentarzem @Vijit dotyczącym obsługi dowiązań symbolicznych. Po pierwsze, użyj getRealPath (). Ale jeśli masz jakieś dowiązania symboliczne, które są folderami, to się nie powiedzie, ponieważ spróbuje wywołać rmdir na link - więc potrzebujesz dodatkowej kontroli.
źródło
Korzystanie z DirectoryIterator odpowiada poprzedniej odpowiedzi…
źródło
Ten działa dla mnie:
źródło
Coś takiego?
źródło
Mała modyfikacja kodu alcuadrado -
glob
nie widzę plików o nazwach z punktów takich jak,.htaccess
więc używam skandiru, a skrypt usuwa się sam - sprawdź__FILE__
.źródło
Przykład dla serwera Linux:
exec('rm -f -r ' . $cache_folder . '/*');
źródło
Usuń wszystkie pliki w folderze
array_map('unlink', glob("$directory/*.*"));
Usuń wszystko. * - Pliki w folderze (bez: „.” I „..”)
array_map('unlink', array_diff(glob("$directory/.*),array("$directory/.","$directory/..")))
Teraz usuń sam folder
rmdir($directory)
źródło
2 centy, aby dodać do tej odpowiedzi powyższej , co jest świetne BTW
Po zeskanowaniu / przeczytaniu katalogu przez funkcję glob (lub podobną) dodaj warunek, aby sprawdzić, czy odpowiedź nie jest pusta lub zostanie
invalid argument supplied for foreach()
wyświetlone ostrzeżenie. Więc...Moja pełna funkcja (jako metoda obiektowa):
źródło
Oto rozwiązanie, które działa idealnie:
źródło
Możesz skopiować pomocników YII
$ katalog (ciąg) - do rekurencyjnego usunięcia.
$ options (array) - do usunięcia katalogu. Prawidłowe opcje to: traverseSymlinks: boolean, czy dowiązania symboliczne do katalogów również powinny być przechodzące. Domyślnie
false
oznacza to, że zawartość dowiązania symbolicznego nie zostanie usunięta. W takim przypadku domyślnym zostanie usunięte tylko dowiązanie symboliczne.źródło
Spróbuj wypróbować poniższy kod z php.net
Pracuj dla mnie dobrze
źródło
Dla Windowsa:
źródło
Podobnie jak rozwiązanie Playnox, ale z eleganckim wbudowanym DirectoryIterator:
źródło
Nie pamiętam, skąd skopiowałem tę funkcję, ale wygląda na to, że nie ma jej na liście i działa dla mnie
źródło
Proste i łatwe...
źródło
A co z tym?
Odniesienie: https://paulund.co.uk/php-delete-directory-and-files-in-directory
źródło
Jeśli nie masz pewności, podana ścieżka to katalog lub plik, możesz użyć tej funkcji do usunięcia ścieżki
źródło