Интересно, как проще всего удалить каталог со всеми его файлами?
я использую rmdir(PATH . '/' . $value);
однако, чтобы удалить папку, если в ней есть файлы, я просто не могу ее удалить.
В настоящее время доступно как минимум два варианта.
Перед удалением папки удалите все ее файлы и папки (а это означает рекурсию!). Вот пример:
public static function deleteDir($dirPath) {
if (! is_dir($dirPath)) {
throw new InvalidArgumentException("$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);
}
И если вы используете 5.2+, вы можете использовать RecursiveIterator, чтобы сделать это без необходимости делать рекурсию самостоятельно:
$dir = 'samples' . DIRECTORY_SEPARATOR . 'sampledirtree';
$it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($it,
RecursiveIteratorIterator::CHILD_FIRST);
foreach($files as $file) {
if ($file->isDir()){
rmdir($file->getRealPath());
} else {
unlink($file->getRealPath());
}
}
rmdir($dir);
Я обычно использую это, чтобы удалить все файлы в папке:
array_map('unlink', glob("$dirname/*.*"));
И тогда вы можете сделать
rmdir($dirname);
Какой самый простой способ удалить каталог со всеми его файлами в нем?
system("rm -rf ".escapeshellarg($dir));
Короткая функция, которая делает работу:
function deleteDir($path) {
return is_file($path) ?
@unlink($path) :
array_map(__FUNCTION__, glob($path.'/*')) == @rmdir($path);
}
Я использую его в классе Utils следующим образом:
class Utils {
public static function deleteDir($path) {
$class_func = array(__CLASS__, __FUNCTION__);
return is_file($path) ?
@unlink($path) :
array_map($class_func, glob($path.'/*')) == @rmdir($path);
}
}
С большой властью приходит большая ответственность: Когда вы вызываете эту функцию с пустым значением, она удалит файлы, начинающиеся с root (/
). В качестве гарантии вы можете проверить, если путь пуст:
function deleteDir($path) {
if (empty($path)) {
return false;
}
return is_file($path) ?
@unlink($path) :
array_map(__FUNCTION__, glob($path.'/*')) == @rmdir($path);
}
Это более короткая версия отлично работает для меня
function deleteDirectory($dirPath) {
if (is_dir($dirPath)) {
$objects = scandir($dirPath);
foreach ($objects as $object) {
if ($object != "." && $object !="..") {
if (filetype($dirPath . DIRECTORY_SEPARATOR . $object) == "dir") {
deleteDirectory($dirPath . DIRECTORY_SEPARATOR . $object);
} else {
unlink($dirPath . DIRECTORY_SEPARATOR . $object);
}
}
}
reset($objects);
rmdir($dirPath);
}
}
Как видно из наиболее популярных комментариев на странице руководства PHP о rmdir()
(увидеть http://php.net/manual/es/function.rmdir.php), glob()
функция не возвращает скрытые файлы. scandir()
предоставляется в качестве альтернативы, которая решает эту проблему.
Алгоритм, описанный там (который работал как обаяние в моем случае):
<?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);
}
?>
Вы можете использовать Symfony’s Файловая система (код):
// composer require symfony/filesystem
use Symfony\Component\Filesystem\Filesystem;
(new Filesystem)->remove($dir);
Однако я не мог удалить некоторые сложные структуры каталогов с помощью этого метода, поэтому сначала вы должны попробовать его, чтобы убедиться, что он работает правильно.
Я мог бы удалить указанную структуру каталогов, используя конкретную реализацию Windows:
$dir = strtr($dir, '/', '\\');
// quotes are important, otherwise one could
// delete "foo" instead of "foo bar"system('RMDIR /S /Q "'.$dir.'"');
И просто для полноты, вот мой старый код:
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 delete_dir($src) {
$dir = opendir($src);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($src . '/' . $file) ) {
delete_dir($src . '/' . $file);
}
else {
unlink($src . '/' . $file);
}
}
}
closedir($dir);
rmdir($src);
}
Функция основана на рекурсии, выполненной для копирования каталога. Вы можете найти эту функцию здесь:
Скопируйте все содержимое одного каталога в другой, используя php