Php удалить папку с файлами
В PHP для этого предусмотрена функция rmdir(). В качестве аргумента она принимает путь до директории, которую Вы хотите удалить. Однако, директория должна быть пустая — это главное условие (если не считать того, что у пользователя, от которого работает веб-сервер, должны быть права на запись для директории). Если в директории будут размещены файлы, то мы получим ошибку при вызове функции. Соответственно, приходим к выводу, что директорию перед использованием функции rmdir() необходимо предварительно очистить.
В сети советуют написать функцию, которой в качестве аргумента будет передаваться путь к директории, которую нам необходимо удалить. В теле функции необходимо организовать листинг содержимого директории, в рамках которого осуществляется проверка — является ли файл директорией. Если файл является директорией, то по данному условию функция вызывает себя. Это необходимо для зачистки вложенных директорий, и это будет работать на всех уровнях вложенности. В ином случае, для файла применяется функция unlink() — она предназначена для удаления файла. За рамками данной проверки на последнем шаге мы удаляем директорию.
Пример реализации:
Какие проблемы у данного кода?
В простых случаях директория со всеми вложениями удалится. Но предположим, что в нашей директории присутствует скрытый файл, который начинается с точки, например, .htaccess. Функция glob() представляет из себя glob-подстановку UNIX, в которой по умолчанию не участвуют скрытые файлы (DOTFILES). Например, если мы зайдем в nix-терминал и будем использовать bash, то мы столкнемся с той же проблемой (речь именно о скрытых файлах в рамках glob). Для решения вопроса в bash существует команда shopt -s dotglob — она разрешает glob-подстановку скрытых файлов. В PHP же это можно решить добавлением дополнительно параметра GLOB_BRACE для glob() и расширением паттерна из первого параметра функции.
И тут так же есть проблема — мы столкнемся с бесконечным циклом, так как в массив войдут значения . и .. — что является на системном уровне текущей и родительской директорией. Придем мы к бесконечному циклу (а не к удалению всех родительских директорий), потому что . в рамках сортировки по умолчанию в сформированном массиве будет первее .. — то есть каждый раз мы будет обращаться к одной и той же директории. Для решения проблемы сформируем массив из данных системных директорий и в цикле удалим их индексы из основного массива. Также существует проблема символьных ссылок. Допустим, что в удаляемой директории размещена ссылка на другую директорию, в удалении содержимого которой мы абсолютно не заинтересованы. Для решения проблемы, перед созданием рекурсии, необходимо организовать проверку на то, что сущность не является ссылкой.
В итоге, функция обретает следующий вид:
Код рабочий, но на самом деле можно было сделать и проще. В PHP существует класс FilesystemIterator, который уже по умолчанию имеет необходимые нам настройки. В конструктор передается путь до директории, листинг которой нам нужен. Нам достаточно просто создать объект.
Обращаю внимание на высокий расход памяти и на то, что зачастую администраторы запрещают использовать на сервере такого рода функции в целях безопасности.
Удаляет файл filename . Функция похожа на функцию unlink() Unix в C. При неудачном выполнении будет вызвана ошибка уровня E_WARNING .
Список параметров
Если файл является символической ссылкой, символическая ссылка будет удалена. В Windows для удаления символической ссылки на каталог вместо этого должна использоваться функция rmdir() .
Возвращаемые значения
Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.
Список изменений
Версия | Описание |
---|---|
7.3.0 | В Windows теперь можно удалить файлы функцией unlink() с использованием дескрипторов, хотя раньше это не удавалось. Тем не менее, всё ещё невозможно повторно создать удалённый файл, пока все дескрипторы к нему не будут закрыты. |
Примеры
Смотрите также
User Contributed Notes 11 notes
This will delete all files in a directory matching a pattern in one line of code.
Deleted a large file but seeing no increase in free space or decrease of disk usage? Using UNIX or other POSIX OS?
The unlink() is not about removing file, it's about removing a file name. The manpage says: ``unlink - delete a name and possibly the file it refers to''.
Most of the time a file has just one name -- removing it will also remove (free, deallocate) the `body' of file (with one caveat, see below). That's the simple, usual case.
However, it's perfectly fine for a file to have several names (see the link() function), in the same or different directories. All the names will refer to the file body and `keep it alive', so to say. Only when all the names are removed, the body of file actually is freed.
The caveat:
A file's body may *also* be `kept alive' (still using diskspace) by a process holding the file open. The body will not be deallocated (will not free disk space) as long as the process holds it open. In fact, there's a fancy way of resurrecting a file removed by a mistake but still held open by a process.
unlink($fileName); failed for me .
Then i tried using the realpath($fileName) function as
unlink(realpath($fileName)); it worked
just posting it , in case if any one finds it useful .
Here the simplest way to delete files with mask
$mask = "*.jpg"
array_map ( "unlink" , glob ( $mask ) );
?>
I have been working on some little tryout where a backup file was created before modifying the main textfile. Then when an error is thrown, the main file will be deleted (unlinked) and the backup file is returned instead.
Though, I have been breaking my head for about an hour on why I couldn't get my persmissions right to unlink the main file.
Finally I knew what was wrong: because I was working on the file and hadn't yet closed the file, it was still in use and ofcourse couldn't be deleted :)
So I thought of mentoining this here, to avoid others of making the same mistake:
// First close the file
fclose ( $fp );
// Then unlink :)
unlink ( $somefile );
?>
To delete all files of a particular extension, or infact, delete all with wildcard, a much simplar way is to use the glob function. Say I wanted to delete all jpgs .
foreach ( glob ( "*.jpg" ) as $filename ) echo " $filename size " . filesize ( $filename ) . "\n" ;
unlink ( $filename );
>
This might seem obvious, but I was tearing my hair out with this problem - make sure the file you're trying to delete isn't currently being used. I had a script that was parsing a text file and was supposed to delete it after completing, but kept getting a permission denied error because I hadn't explicitly closed the file, hence it was technically still being "used" even though the parsing was complete.
To anyone who's had a problem with the permissions denied error, it's sometimes caused when you try to delete a file that's in a folder higher in the hierarchy to your working directory (i.e. when trying to delete a path that starts with "../").
So to work around this problem, you can use chdir() to change the working directory to the folder where the file you want to unlink is located.
$old = getcwd (); // Save the current directory
chdir ( $path_to_file );
unlink ( $filename );
chdir ( $old ); // Restore the old working directory
?>
On OSX, when fighting against a "Permission Denied" error, make sure, the directory has WRITE permissions for the executing php-user.
Furthermore, if you rely on ACLs, and want to delete a file or symlink, the containing directory needs to have "delete_child" permission in order to unlink things inside. If you only grant "delete" to the folder that will allow you to delete the container folder itself, but not the objects inside.
unlink works the same as the rm command on nix based loses or del command on windows, it will not resolve the file but remove the exact path given even if that path is just a link.
E.G
/var/www/test/index.php = symlink(/home/test/www/index.php)
unlink ( "/var/www/test/index.php" );
?>
Will just delete the link, not the original file where as
unlink ( "/home/test/www/index.php" );
?>
Will unlink the original file path and break the symlink, and allow the system to overwrite as the filesystem will not know of the file's location anymore.
The best way to delete files by mask is as follows:
array_walk ( glob ( '/etc/*' ), 'unlink' );
?>
Do not use array_map mentioned below - it's purpose is to process values in a given array AND COLLECT data returned by the callback function. So, array_map is slower and uses additional memory compared to array_walk.
Пытается удалить директорию с именем directory . Директория должна быть пустой и должны иметься необходимые для этого права. При неудачном выполнении будет сгенерирована ошибка уровня E_WARNING .
Список параметров
Путь к директории.
Возвращаемые значения
Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.
Примеры
Смотрите также
- is_dir() - Определяет, является ли имя файла директорией
- mkdir() - Создаёт директорию
- unlink() - Удаляет файл
User Contributed Notes 29 notes
Glob function doesn't return the hidden files, therefore scandir can be more useful, when trying to delete recursively a tree.
public static 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 );
>
?>
The function delTree is dangerous when you dont take really care. I for example always deleted a temporary directory with it. Everthing went fine until the moment where the var containing this temporary directory wasnt set. The var didnt contain the path but an empty string. The function delTree was called and deleted all the files at my host!
So dont use this function when you dont have a proper handling coded. Dont think about using this function only for testing without such a handling.
Luckily nothing is lost because I had the local copy.
Never ever use jurchiks101 at gmail dot com code. It contains command injection vulnerability.
If you want to do it that way, use something like this instead:
if ( PHP_OS === 'Windows' )
exec ( sprintf ( "rd /s /q %s" , escapeshellarg ( $path )));
>
else
exec ( sprintf ( "rm -rf %s" , escapeshellarg ( $path )));
>
?>
Note the escapeshellarg usage to escape any possible unwanted character, this avoids putting commands in $path variable so the possibility of someone "pwning" the server with this code
some implementations of recursive folder delete don't work so well (some give warnings, other don't delete hidden files etc).
this one is working fine:
function rrmdir ( $src ) $dir = opendir ( $src );
while( false !== ( $file = readdir ( $dir )) ) if (( $file != '.' ) && ( $file != '..' )) $full = $src . '/' . $file ;
if ( is_dir ( $full ) ) rrmdir ( $full );
>
else unlink ( $full );
>
>
>
closedir ( $dir );
rmdir ( $src );
>
I was working on some Dataoperation, and just wanted to share an OOP method with you.
It just removes any contents of a Directory but not the target Directory itself! Its really nice if you want to clean a BackupDirectory or Log.
Also you can test on it if something went wrong or if it just done its Work!
I have it in a FileHandler class for example, enjoy!
public function deleteContent ( $path ) try $iterator = new DirectoryIterator ( $path );
foreach ( $iterator as $fileinfo ) if( $fileinfo -> isDot ())continue;
if( $fileinfo -> isDir ()) if( deleteContent ( $fileinfo -> getPathname ()))
@ rmdir ( $fileinfo -> getPathname ());
>
if( $fileinfo -> isFile ()) @ unlink ( $fileinfo -> getPathname ());
>
>
> catch ( Exception $e ) // write log
return false ;
>
return true ;
>
Say, you're working on Windows and continue to get a permission's error without a reason. Then it may be that a different Windows program is working on the folder (see earlier notes also). In the case that you can't find that program, the line
may solve the problem!
Make sure to write this before rmdir($dirname);.
Another simple way to recursively delete a directory that is not empty:
itay at itgoldman's function falls into an infinite loop if the $src directory doesn't exist.
Here's a fix - one should do at least a file_exists() check before the loop:
Thanks to itay for the original function, though, it was helpful.
// Recursive PHP function to completely remove a directory
function delete_directory_recursively( $path )
$dir = new \DirectoryIterator( $path );
// Iterate through the subdirectories / files of the provided directory
foreach ( $dir as $dir_info )
// Exclude the . (current directory) and .. (parent directory) paths
// from the directory iteration
if ( ! $dir_info->isDot() )
// Get the full currently iterated path
$iterated_path = $dir_info->getPathname();
// If the currently iterated path is a directory
if ( $dir_info->isDir() )
// which is not empty (in which case scandir returns an array of not 2 (. and ..) elements)
if ( count( scandir( $iterated_path ) ) !== 2 )
// Call the function recursively
self::remove_directory_recursively( $iterated_path );
// if the currently iterated path is an empty directory, remove it
rmdir( $iterated_path );
// If the currently iterated path describes a file, we need to
// delete that file
unlink( $iterated_path );
> // loop which opens if the currently iterated directory is neither . nor ..
> // end of iteration through directories / files of provided path
// After iterating through the subpaths of the provided path, remove the
// concerned path
rmdir( $path );
> // end of delete_directory_recursively() function definition
I also ran into the permissions issue in Windows when deleting a folder and the solution was to close all editors which had files opened which were located in the folder structure.
This issue has been driving me nuts for hours.
I am running PHP on IIS, I had the wincache module installed, when running a recursive delete a certain folder would get "stuck" and throw permissions errors. I was not able to delete them with PHP or in windows itself. The only way to delete the folder was to wait 5 min and run the script again, or stop the IIS server and the folder would delete on its own. Disabling the wincachce module resolved the issue.
Hope this helps.
function unlinkDir($dir)
$dirs = array($dir);
$files = array() ;
for($i=0;;$i++)
if(isset($dirs[$i]))
$dir = $dirs[$i];
else
break ;
if($openDir = opendir($dir))
while($readDir = @readdir($openDir))
if($readDir != "." && $readDir != "..")
foreach($files as $file)
unlink($file) ;
>
$dirs = array_reverse($dirs) ;
foreach($dirs as $dir)
rmdir($dir) ;
>
It is rather dangerous to recurse into symbolically linked directories. The delTree should be modified to check for links.
public static function delTree ( $dir ) <
$files = array_diff ( scandir ( $dir ), array( '.' , '..' ));
foreach ( $files as $file ) <
( is_dir ( " $dir / $file " ) && ! is_link ( $dir )) ? delTree ( " $dir / $file " ) : unlink ( " $dir / $file " );
>
return rmdir ( $dir );
>
?>
it Will Delete All Fildes in folder and that folder too.
echo $path = 'D:\xampp\htdocs\New folder\New folder';
function rmdir_recursive($dir) $it = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
$it = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
foreach($it as $file) if ($file->isDir()) rmdir($file->getPathname());
else unlink($file->getPathname());
>
rmdir($dir);
>
rmdir_recursive($path);
I've noticed that when using this command on a windows platform you may encounter a permissions error which may seem unwarranted. This commonly occurs if you are or were using a program to edit something in the to be deleted folder and either the item is still in the folder or the program that was accessing the file in that folder is still running(causing it to hold onto the folder).
SO. if you get a permissions error and there shouldn't be an issue with folder permissions check if there are files in there then check if there is a program running that is or was using a file that was in that folder and kill it.
Keep in mind that if you know what your host OS is, you can always just call the appropriate system call using exec() or the like. For example:
exec('rmdir folder-to-delete /s /q'); //windows
exec('rmdir -rf folder-to-delete'); //OS X/*nix?
while ($contents = readdir($directoryHandle))
if a folder named 0 (zero) is found during traversing the hierarchy
Works fine, tested on PHP 5.4(EasyPHP server)
function deletedir($dir)
if (is_dir($dir))
<
$files = scandir($dir);
foreach ($files as $file)
<
if ($file != "." && $file != "..")
<
if (filetype($dir."/".$file) == "dir")
$this->deletedir($dir."/".$file);
>
else
unlink($dir."/".$file);
>
>
>
reset($objects);
if(rmdir($dir))
return 'deleted successfully!';
>
else
return 'delete failed!';
>
>
else
return 'doesn\'t exist or inaccessible!';
>
>
Something to note:
You have to take care of file permission if necessary
A patch to previous script to make sure rights for deletion is set:
//Delete folder function
function deleteDirectory ( $dir ) <
if (! file_exists ( $dir )) return true ;
if (! is_dir ( $dir ) || is_link ( $dir )) return unlink ( $dir );
foreach ( scandir ( $dir ) as $item ) <
if ( $item == '.' || $item == '..' ) continue;
if (! deleteDirectory ( $dir . "/" . $item )) <
chmod ( $dir . "/" . $item , 0777 );
if (! deleteDirectory ( $dir . "/" . $item )) return false ;
>;
>
return rmdir ( $dir );
>
?>
[EDITOR NOTE: "Credits to erkethan at free dot fr." - thiago]
Sometimes you would face situations in which rmdir($dirname) would give "permission denied" errors though you may have changed $dirname permissions. In such situations just change the permissions of the directory which contains $dirname and rmdir($dirname) would work like a charm.
Say you use rmdir('dirr'); then change the permissions of the folder that contains 'dirr'.
if you get this problem Permission denied in windows testing your site maybe this will resolve the problem
if( file_exists ( $path . '/Thumbs.db' )) <
unlink ( $path . '/Thumbs.db' );
>
?>
and then
In case you're trying to rmdir() and you keep getting 'Permission denied' errors, make sure you don't have the directory still open after using opendir(). Especially when writing recursive functions for deleting directories, make sure you have closedir() BEFORE rmdir().
I wasn't having much luck with the recursive delete functions below, so I wrote my own:
// ensure $dir ends with a slash
function delTree ( $dir ) <
$files = glob ( $dir . '*' , GLOB_MARK );
foreach( $files as $file ) <
if( substr ( $file , - 1 ) == '/' )
delTree ( $file );
else
unlink ( $file );
>
rmdir ( $dir );
>
?>
Simple. Works.
Concise way to recursively remove a directory:
This isn't my code, but just thought I would share, since it took me so long to find. This is a function to delete a folder, all sub-folders, and files in one clean move.
Just tell it what directory you want deleted, in relation to the page that this function is executed. Then set $empty = true if you want the folder just emptied, but not deleted. If you set $empty = false, or just simply leave it out, the given directory will be deleted, as well.
function deleteAll ( $directory , $empty = false ) <
if( substr ( $directory ,- 1 ) == "/" ) <
$directory = substr ( $directory , 0 ,- 1 );
>
if(! file_exists ( $directory ) || ! is_dir ( $directory )) <
return false ;
> elseif(! is_readable ( $directory )) <
return false ;
> else <
$directoryHandle = opendir ( $directory );
if( is_dir ( $path )) <
deleteAll ( $path );
> else <
unlink ( $path );
>
>
>
if( $empty == false ) <
if(! rmdir ( $directory )) <
return false ;
>
>
I had situation where the rmdir was returning warning message as within last loop it was already removed. So here is quick fix by adding is_dir to the DelTree routine below
function delTree ( $dir ) <
$files = glob ( $dir . '*' , GLOB_MARK );
foreach( $files as $file ) <
if( substr ( $file , - 1 ) == '/' )
delTree ( $file );
else
unlink ( $file );
>
В предыдущей статье мы с Вами разбирали функции для работы с каталогами в PHP, и там я познакомил Вас с функцией rmdir(), которая удаляет каталог. Однако, я сказал, что таким способом получится удалить только пустую директорию, а вот как удалить каталог с файлами, Вы узнаете сейчас.
Принцип очень простой: чтобы удалить каталог с файлами, надо удалить сначала все файлы, а также все подкаталоги. Внутри подкаталогов могут быть также файлы и другие подкаталоги, их также надо очистить. В общем, сложность состоит в том, что глубина каталогов может быть очень большой. И очевидно, что напрашивается рекурсия - вызов функции внутри самой себя.
Несмотря на кажущуюся сложность алгоритма, реализация очень простая и прозрачная:
function removeDirectory($dir) if ($objs = glob($dir."/*")) foreach($objs as $obj) is_dir($obj) ? removeDirectory($obj) : unlink($obj);
>
>
rmdir($dir);
>
?>
Постараюсь объяснить понятным языком алгоритм работы данной функции. Первым делом мы получаем список всех файлов внутри заданной директории. Если их там нет, то сразу удаляем её. Если они есть, то начинаем по-очереди перебирать. Если элемент является файлом, то просто удаляем его (unlink($obj)). Если же это каталог, то вызываем вновь нашу функцию, передав этот каталог. Это и есть рекурсия: функция вызывает сама себя. После вызова функцией самой себя всё начинается заново, но уже с другой директорией. У ней также удаляются все файлы, а все её директории отправляются вновь в эту функцию. Когда все директории и файлы удалены, у нас удаляется уже пустой каталог.
Я Вам скажу так, данный алгоритм не столько полезен с точки зрения практики (не так часто приходится удалять каталоги с файлами в PHP), сколько полезен для развития Вашего мышления. Это очень простой алгоритм и решает он весьма и весьма сложную задачу. Поэтому учитесь составлять алгоритмы - это самое главное в любом языке программирования.
Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления
Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.
Порекомендуйте эту статью друзьям:
Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):
Она выглядит вот так:
Комментарии ( 8 ):
Михаил подскажите как удалить в папке несколько файлов png. Я пол дня провел над этой задачей. Прошу подсказать ))) Очень нужно.
Получаете список файлов из каталога и удаляете их в цикле через unlink().
Михаил, читаю ваши уроки с самого начала и не смог обнаружить у вас пояснения двух знаков, и их применение - ? : ; Например тут is_dir($obj) ? removeDirectory($obj) : unlink($obj); И что такое is_dir()?
Подобная запись является аналогом цикла if и оформляется по такой форме: Условие ? Выражение1 : Выражение2 Выражение1 выполнится если Условие истино, Выражение2 если ложно, т.е. else. Например: $x>=$y ? echo("Икс больше либо равен игрику") : echo(Икс меньше игрика); равносильно if($x>=$y) < echo("Икс больше либо равен игрику"); >else
Attempts to remove the directory named by directory . The directory must be empty, and the relevant permissions must permit this. A E_WARNING level error will be generated on failure.
Parameters
Path to the directory.
Return Values
Returns true on success or false on failure.
Examples
See Also
- is_dir() - Tells whether the filename is a directory
- mkdir() - Makes directory
- unlink() - Deletes a file
User Contributed Notes 29 notes
Glob function doesn't return the hidden files, therefore scandir can be more useful, when trying to delete recursively a tree.
public static 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 );
>
?>
The function delTree is dangerous when you dont take really care. I for example always deleted a temporary directory with it. Everthing went fine until the moment where the var containing this temporary directory wasnt set. The var didnt contain the path but an empty string. The function delTree was called and deleted all the files at my host!
So dont use this function when you dont have a proper handling coded. Dont think about using this function only for testing without such a handling.
Luckily nothing is lost because I had the local copy.
Never ever use jurchiks101 at gmail dot com code. It contains command injection vulnerability.
If you want to do it that way, use something like this instead:
if ( PHP_OS === 'Windows' )
exec ( sprintf ( "rd /s /q %s" , escapeshellarg ( $path )));
>
else
exec ( sprintf ( "rm -rf %s" , escapeshellarg ( $path )));
>
?>
Note the escapeshellarg usage to escape any possible unwanted character, this avoids putting commands in $path variable so the possibility of someone "pwning" the server with this code
some implementations of recursive folder delete don't work so well (some give warnings, other don't delete hidden files etc).
this one is working fine:
function rrmdir ( $src ) $dir = opendir ( $src );
while( false !== ( $file = readdir ( $dir )) ) if (( $file != '.' ) && ( $file != '..' )) $full = $src . '/' . $file ;
if ( is_dir ( $full ) ) rrmdir ( $full );
>
else unlink ( $full );
>
>
>
closedir ( $dir );
rmdir ( $src );
>
I was working on some Dataoperation, and just wanted to share an OOP method with you.
It just removes any contents of a Directory but not the target Directory itself! Its really nice if you want to clean a BackupDirectory or Log.
Also you can test on it if something went wrong or if it just done its Work!
I have it in a FileHandler class for example, enjoy!
public function deleteContent ( $path ) try $iterator = new DirectoryIterator ( $path );
foreach ( $iterator as $fileinfo ) if( $fileinfo -> isDot ())continue;
if( $fileinfo -> isDir ()) if( deleteContent ( $fileinfo -> getPathname ()))
@ rmdir ( $fileinfo -> getPathname ());
>
if( $fileinfo -> isFile ()) @ unlink ( $fileinfo -> getPathname ());
>
>
> catch ( Exception $e ) // write log
return false ;
>
return true ;
>
Say, you're working on Windows and continue to get a permission's error without a reason. Then it may be that a different Windows program is working on the folder (see earlier notes also). In the case that you can't find that program, the line
may solve the problem!
Make sure to write this before rmdir($dirname);.
Another simple way to recursively delete a directory that is not empty:
itay at itgoldman's function falls into an infinite loop if the $src directory doesn't exist.
Here's a fix - one should do at least a file_exists() check before the loop:
Thanks to itay for the original function, though, it was helpful.
// Recursive PHP function to completely remove a directory
function delete_directory_recursively( $path )
$dir = new \DirectoryIterator( $path );
// Iterate through the subdirectories / files of the provided directory
foreach ( $dir as $dir_info )
// Exclude the . (current directory) and .. (parent directory) paths
// from the directory iteration
if ( ! $dir_info->isDot() )
// Get the full currently iterated path
$iterated_path = $dir_info->getPathname();
// If the currently iterated path is a directory
if ( $dir_info->isDir() )
// which is not empty (in which case scandir returns an array of not 2 (. and ..) elements)
if ( count( scandir( $iterated_path ) ) !== 2 )
// Call the function recursively
self::remove_directory_recursively( $iterated_path );
// if the currently iterated path is an empty directory, remove it
rmdir( $iterated_path );
// If the currently iterated path describes a file, we need to
// delete that file
unlink( $iterated_path );
> // loop which opens if the currently iterated directory is neither . nor ..
> // end of iteration through directories / files of provided path
// After iterating through the subpaths of the provided path, remove the
// concerned path
rmdir( $path );
> // end of delete_directory_recursively() function definition
I also ran into the permissions issue in Windows when deleting a folder and the solution was to close all editors which had files opened which were located in the folder structure.
This issue has been driving me nuts for hours.
I am running PHP on IIS, I had the wincache module installed, when running a recursive delete a certain folder would get "stuck" and throw permissions errors. I was not able to delete them with PHP or in windows itself. The only way to delete the folder was to wait 5 min and run the script again, or stop the IIS server and the folder would delete on its own. Disabling the wincachce module resolved the issue.
Hope this helps.
function unlinkDir($dir)
$dirs = array($dir);
$files = array() ;
for($i=0;;$i++)
if(isset($dirs[$i]))
$dir = $dirs[$i];
else
break ;
if($openDir = opendir($dir))
while($readDir = @readdir($openDir))
if($readDir != "." && $readDir != "..")
foreach($files as $file)
unlink($file) ;
>
$dirs = array_reverse($dirs) ;
foreach($dirs as $dir)
rmdir($dir) ;
>
It is rather dangerous to recurse into symbolically linked directories. The delTree should be modified to check for links.
public static function delTree ( $dir ) <
$files = array_diff ( scandir ( $dir ), array( '.' , '..' ));
foreach ( $files as $file ) <
( is_dir ( " $dir / $file " ) && ! is_link ( $dir )) ? delTree ( " $dir / $file " ) : unlink ( " $dir / $file " );
>
return rmdir ( $dir );
>
?>
it Will Delete All Fildes in folder and that folder too.
echo $path = 'D:\xampp\htdocs\New folder\New folder';
function rmdir_recursive($dir) $it = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
$it = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
foreach($it as $file) if ($file->isDir()) rmdir($file->getPathname());
else unlink($file->getPathname());
>
rmdir($dir);
>
rmdir_recursive($path);
I've noticed that when using this command on a windows platform you may encounter a permissions error which may seem unwarranted. This commonly occurs if you are or were using a program to edit something in the to be deleted folder and either the item is still in the folder or the program that was accessing the file in that folder is still running(causing it to hold onto the folder).
SO. if you get a permissions error and there shouldn't be an issue with folder permissions check if there are files in there then check if there is a program running that is or was using a file that was in that folder and kill it.
Keep in mind that if you know what your host OS is, you can always just call the appropriate system call using exec() or the like. For example:
exec('rmdir folder-to-delete /s /q'); //windows
exec('rmdir -rf folder-to-delete'); //OS X/*nix?
while ($contents = readdir($directoryHandle))
if a folder named 0 (zero) is found during traversing the hierarchy
Works fine, tested on PHP 5.4(EasyPHP server)
function deletedir($dir)
if (is_dir($dir))
<
$files = scandir($dir);
foreach ($files as $file)
<
if ($file != "." && $file != "..")
<
if (filetype($dir."/".$file) == "dir")
$this->deletedir($dir."/".$file);
>
else
unlink($dir."/".$file);
>
>
>
reset($objects);
if(rmdir($dir))
return 'deleted successfully!';
>
else
return 'delete failed!';
>
>
else
return 'doesn\'t exist or inaccessible!';
>
>
Something to note:
You have to take care of file permission if necessary
A patch to previous script to make sure rights for deletion is set:
//Delete folder function
function deleteDirectory ( $dir ) <
if (! file_exists ( $dir )) return true ;
if (! is_dir ( $dir ) || is_link ( $dir )) return unlink ( $dir );
foreach ( scandir ( $dir ) as $item ) <
if ( $item == '.' || $item == '..' ) continue;
if (! deleteDirectory ( $dir . "/" . $item )) <
chmod ( $dir . "/" . $item , 0777 );
if (! deleteDirectory ( $dir . "/" . $item )) return false ;
>;
>
return rmdir ( $dir );
>
?>
[EDITOR NOTE: "Credits to erkethan at free dot fr." - thiago]
Sometimes you would face situations in which rmdir($dirname) would give "permission denied" errors though you may have changed $dirname permissions. In such situations just change the permissions of the directory which contains $dirname and rmdir($dirname) would work like a charm.
Say you use rmdir('dirr'); then change the permissions of the folder that contains 'dirr'.
if you get this problem Permission denied in windows testing your site maybe this will resolve the problem
if( file_exists ( $path . '/Thumbs.db' )) <
unlink ( $path . '/Thumbs.db' );
>
?>
and then
In case you're trying to rmdir() and you keep getting 'Permission denied' errors, make sure you don't have the directory still open after using opendir(). Especially when writing recursive functions for deleting directories, make sure you have closedir() BEFORE rmdir().
I wasn't having much luck with the recursive delete functions below, so I wrote my own:
// ensure $dir ends with a slash
function delTree ( $dir ) <
$files = glob ( $dir . '*' , GLOB_MARK );
foreach( $files as $file ) <
if( substr ( $file , - 1 ) == '/' )
delTree ( $file );
else
unlink ( $file );
>
rmdir ( $dir );
>
?>
Simple. Works.
Concise way to recursively remove a directory:
This isn't my code, but just thought I would share, since it took me so long to find. This is a function to delete a folder, all sub-folders, and files in one clean move.
Just tell it what directory you want deleted, in relation to the page that this function is executed. Then set $empty = true if you want the folder just emptied, but not deleted. If you set $empty = false, or just simply leave it out, the given directory will be deleted, as well.
function deleteAll ( $directory , $empty = false ) <
if( substr ( $directory ,- 1 ) == "/" ) <
$directory = substr ( $directory , 0 ,- 1 );
>
if(! file_exists ( $directory ) || ! is_dir ( $directory )) <
return false ;
> elseif(! is_readable ( $directory )) <
return false ;
> else <
$directoryHandle = opendir ( $directory );
if( is_dir ( $path )) <
deleteAll ( $path );
> else <
unlink ( $path );
>
>
>
if( $empty == false ) <
if(! rmdir ( $directory )) <
return false ;
>
>
I had situation where the rmdir was returning warning message as within last loop it was already removed. So here is quick fix by adding is_dir to the DelTree routine below
function delTree ( $dir ) <
$files = glob ( $dir . '*' , GLOB_MARK );
foreach( $files as $file ) <
if( substr ( $file , - 1 ) == '/' )
delTree ( $file );
else
unlink ( $file );
>
Читайте также: