Я пытаюсь удалить каталог с rmdir, но я получил сообщение «Directory not empty», потому что в нем все еще есть файлы.
Какую функцию я могу использовать для удаления каталога со всеми файлами в нем?
Для этого нет встроенной функции, но см. Комментарии внизу 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
если хотите, чтобы все было просто. Это делает ваш скрипт 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
В вышеприведенном сообщении ( Джон Кугельман ) я полагаю, что парсер 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; }
Попробуйте следующую удобную функцию:
/** * 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); }