Рекурсивная функция удаления каталога для PHP?

Я использую PHP для перемещения содержимого подпапки изображений

GalleryName / изображения /

в другую папку. После перемещения мне нужно удалить каталог GalleryName и все остальное внутри него .

Я знаю, что rmdir() не будет работать, если каталог не пуст. Я потратил некоторое время на создание рекурсивной функции для scandir() начиная с вершины, а затем unlink() если это файл и scandir() если это каталог, а затем rmdir() каждый пустой каталог, когда я иду.

Пока это не работает правильно, и я начал думать – разве это не смехотворно простая функция, которую должен делать PHP? Удаление каталога?

Так что-то мне не хватает? Или есть, по крайней мере, проверенная функция, которую люди используют для этого действия?

Любая помощь будет оценена по достоинству.

PS Я доверяю вам всем здесь больше, чем комментарии на сайте php.net – там есть сотни функций, но мне интересно услышать, если кто-то из вас здесь рекомендует друг друга.

Solutions Collecting From Web of "Рекурсивная функция удаления каталога для PHP?"

Как насчет этой проблемы?

 foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dirPath, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $path) { $path->isDir() && !$path->isLink() ? rmdir($path->getPathname()) : unlink($path->getPathname()); } rmdir($dirPath); 

Это рекурсивная функция, которую я создал / модифицировал и которая, похоже, работает. Надеюсь, в этом нет ничего слишком опасного.

 function destroy_dir($dir) { if (!is_dir($dir) || is_link($dir)) return unlink($dir); foreach (scandir($dir) as $file) { if ($file == '.' || $file == '..') continue; if (!destroy_dir($dir . DIRECTORY_SEPARATOR . $file)) { chmod($dir . DIRECTORY_SEPARATOR . $file, 0777); if (!destroy_dir($dir . DIRECTORY_SEPARATOR . $file)) return false; }; } return rmdir($dir); } 

Если сервер приложения запускает linux, просто используйте функцию shell_exec () и предоставьте ему команду rm -R, например:

 shell_exec("rm ".$dir_path." -R"); 

Объяснение:

Функция будет запускать введенную команду непосредственно в linux. Это то же самое, что и команда в терминале linux.

Команда rm удаляет файл или каталог, переданные в $dir_path а опция -R указывает системе на ее рекурсивное выполнение.

Я адаптировал функцию, которая обрабатывает скрытые файлы unix с префиксом точки и использует glob:

 public static function deleteDir($path) { if (!is_dir($path)) { throw new InvalidArgumentException("$path is not a directory"); } if (substr($path, strlen($path) - 1, 1) != '/') { $path .= '/'; } $dotfiles = glob($path . '.*', GLOB_MARK); $files = glob($path . '*', GLOB_MARK); $files = array_merge($files, $dotfiles); foreach ($files as $file) { if (basename($file) == '.' || basename($file) == '..') { continue; } else if (is_dir($file)) { self::deleteDir($file); } else { unlink($file); } } rmdir($path); } 

Существует еще один поток с большим количеством примеров здесь: Как я рекурсивно удаляю каталог и все его содержимое (файлы + sub dirs) в PHP?

Если вы используете Yii, вы можете оставить его в рамке:

 CFileHelper::removeDirectory($my_directory); 

Я предпочитаю расширенный метод, полученный на страницах справки php http://php.net/manual/en/function.rmdir.php#115598

  // check accidential empty, root or relative pathes if (!empty($path) && ...) { if (PHP_OS === 'Windows') { exec('rd /s /q "'.$path.'"'); } else { exec('rm -rf "'.$path.'"'); } } else { error_log('path not valid:$path'.var_export($path, true)); } 

причины моего решения:

  • меньше кода
  • скорость
  • будь проще