Я пытаюсь удалить каталог с помощью rmdir
, но я получил сообщение "Каталог не пуст", потому что в нем все еще есть файлы.
Какую функцию я могу использовать для удаления каталога со всеми файлами в нем?
Я пытаюсь удалить каталог с помощью rmdir
, но я получил сообщение "Каталог не пуст", потому что в нем все еще есть файлы.
Какую функцию я могу использовать для удаления каталога со всеми файлами в нем?
Для этого нет встроенной функции, но см. комментарии внизу http://us3.php.net/rmdir. Ряд комментаторов разместили свои собственные функции рекурсивного удаления каталогов. Вы можете выбрать из них.
Здесь тот, который выглядит достойно:
function deleteDirectory($dir) {
if (!file_exists($dir)) {
return true;
}
if (!is_dir($dir)) {
return unlink($dir);
}
foreach (scandir($dir) as $item) {
if ($item == '.' || $item == '..') {
continue;
}
if (!deleteDirectory($dir . DIRECTORY_SEPARATOR . $item)) {
return false;
}
}
return rmdir($dir);
}
Изменить: Вы можете просто вызвать rm -rf
, если хотите, чтобы все было просто. Это делает ваш script UNIX-only, поэтому остерегайтесь этого. Если вы идете по этому маршруту, я бы попробовал что-то вроде:
function deleteDirectory($dir) {
system('rm -rf ' . escapeshellarg($dir), $retval);
return $retval == 0; // UNIX commands return zero on success
}
Вы всегда можете попытаться использовать системные команды.
Если на linux используется: rm -rf /dir
Если в окнах используется: rd c:\dir /S /Q
В вышеприведенном сообщении (John Kugelman) Я полагаю, что парсер PHP оптимизирует этот скандир в foreach, но мне просто кажется неправильным, чтобы scandir
в выражении условия foreach
.
Вы также можете просто сделать две команды array_shift
, чтобы удалить .
и ..
вместо того, чтобы всегда проверять цикл.
function rrmdir($dir)
{
if (is_dir($dir))
{
$objects = scandir($dir);
foreach ($objects as $object)
{
if ($object != '.' && $object != '..')
{
if (filetype($dir.'/'.$object) == 'dir') {rrmdir($dir.'/'.$object);}
else {unlink($dir.'/'.$object);}
}
}
reset($objects);
rmdir($dir);
}
}
Вот что я использовал:
function emptyDir($dir) {
if (is_dir($dir)) {
$scn = scandir($dir);
foreach ($scn as $files) {
if ($files !== '.') {
if ($files !== '..') {
if (!is_dir($dir . '/' . $files)) {
unlink($dir . '/' . $files);
} else {
emptyDir($dir . '/' . $files);
rmdir($dir . '/' . $files);
}
}
}
}
}
}
$dir = 'link/to/your/dir';
emptyDir($dir);
rmdir($dir);
В моем случае было довольно много сложных справочников (имена, содержащие специальные символы, глубокое вложение и т.д.) и скрытые файлы, которые приводили к ошибкам "Directory not empty" с другими предлагаемыми решениями. Поскольку решение Unix было неприемлемым, я тестировал, пока не пришел к следующему решению (которое хорошо срабатывало в моем случае):
function removeDirectory($path) {
// The preg_replace is necessary in order to traverse certain types of folder paths (such as /dir/[[dir2]]/dir3.abc#/)
// The {,.}* with GLOB_BRACE is necessary to pull all hidden files (have to remove or get "Directory not empty" errors)
$files = glob(preg_replace('/(\*|\?|\[)/', '[$1]', $path).'/{,.}*', GLOB_BRACE);
foreach ($files as $file) {
if ($file == $path.'/.' || $file == $path.'/..') { continue; } // skip special dir entries
is_dir($file) ? removeDirectory($file) : unlink($file);
}
rmdir($path);
return;
}
Не могу придумать более простой и эффективный способ сделать это, чем этот
<?php
$dirname = './myfolder';
if (is_dir($dirname)) {
$dir = new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS);
foreach (new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST ) as $filename => $file) {
if (is_file($filename))
unlink($filename);
else
rmdir($filename);
}
rmdir($dirname); // Now remove myfolder
}
?>
Я не пришел, чтобы удалить папку, потому что PHP сказал мне, что она не была пустой. Но это было. Функция Намана была хорошим решением для завершения моей. Вот что я использую:
function emptyDir($dir) {
if (is_dir($dir)) {
$scn = scandir($dir);
foreach ($scn as $files) {
if ($files !== '.') {
if ($files !== '..') {
if (!is_dir($dir . '/' . $files)) {
unlink($dir . '/' . $files);
} else {
emptyDir($dir . '/' . $files);
rmdir($dir . '/' . $files);
}
}
}
}
}
}
function deleteDir($dir) {
foreach(glob($dir . '/' . '*') as $file) {
if(is_dir($file)){
deleteDir($file);
} else {
unlink($file);
}
}
emptyDir($dir);
rmdir($dir);
}
Итак, чтобы удалить каталог и рекурсивно его содержимое:
deleteDir($dir);
Попробуйте следующую удобную функцию:
/**
* Removes directory and its contents
*
* @param string $path Path to the directory.
*/
function _delete_dir($path) {
if (!is_dir($path)) {
throw new InvalidArgumentException("$path must be a directory");
}
if (substr($path, strlen($path) - 1, 1) != DIRECTORY_SEPARATOR) {
$path .= DIRECTORY_SEPARATOR;
}
$files = glob($path . '*', GLOB_MARK);
foreach ($files as $file) {
if (is_dir($file)) {
_delete_dir($file);
} else {
unlink($file);
}
}
rmdir($path);
}
С помощью этой функции вы сможете удалить любой файл или папку
function deleteDir($dirPath)
{
if (!is_dir($dirPath)) {
if (file_exists($dirPath) !== false) {
unlink($dirPath);
}
return;
}
if ($dirPath[strlen($dirPath) - 1] != '/') {
$dirPath .= '/';
}
$files = glob($dirPath . '*', GLOB_MARK);
foreach ($files as $file) {
if (is_dir($file)) {
deleteDir($file);
} else {
unlink($file);
}
}
rmdir($dirPath);
}
От http://php.net/manual/en/function.rmdir.php#91797
Функция glob не возвращает скрытые файлы, поэтому scandir может быть более полезен при попытке рекурсивного удаления дерева.
<?php
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);
}
?>