Интересно, что самый простой способ удалить каталог со всеми его файлами?
Я использую 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); } ?>
Здесь у вас есть одна хорошая и простая рекурсия для удаления всех файлов в исходном каталоге, включая этот каталог:
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
Вы можете использовать файловую систему Symfony ( код ):
// 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); }
Я предпочитаю это, потому что он по-прежнему возвращает TRUE, когда он преуспевает, и FALSE, когда он терпит неудачу, а также предотвращает ошибку, где пустые пути могут попробовать и удалить все из «/ *» !!:
function deleteDir($path) { return !empty($path) && is_file($path) ? @unlink($path) : (array_reduce(glob($path.'/*'), function ($r, $i) { return $r && deleteDir($i); }, TRUE)) && @rmdir($path); }
Как насчет этого:
function recursiveDelete($dirPath, $deleteParent = true){ foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dirPath, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $path) { $path->isFile() ? unlink($path->getPathname()) : rmdir($path->getPathname()); } if($deleteParent) rmdir($dirPath); }
Litle bit изменить код alcuadrado – glob
не видит файлы с именем из таких точек, как .htaccess
поэтому я использую scandir, а скрипт удаляет сам себя – проверьте __FILE__
.
function deleteDir($dirPath) { if (!is_dir($dirPath)) { throw new InvalidArgumentException("$dirPath must be a directory"); } if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') { $dirPath .= '/'; } $files = scandir($dirPath); foreach ($files as $file) { if ($file === '.' || $file === '..') continue; if (is_dir($dirPath.$file)) { deleteDir($dirPath.$file); } else { if ($dirPath.$file !== __FILE__) { unlink($dirPath.$file); } } } rmdir($dirPath); }
Лучшее решение для меня
my_folder_delete("../path/folder");
код:
function my_folder_delete($path) { if(!empty($path) && is_dir($path) ){ $dir = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS); //upper dirs are not included,otherwise DISASTER HAPPENS :) $files = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST); foreach ($files as $f) {if (is_file($f)) {unlink($f);} else {$empty_dirs[] = $f;} } if (!empty($empty_dirs)) {foreach ($empty_dirs as $eachDir) {rmdir($eachDir);}} rmdir($path); } }
ПОМНИТЕ!
не пропускайте ПУСТОЙ ЦЕННОСТИ в любой каталог, удаляющий функции !!! (резервируйте их всегда, иначе в один прекрасный день вы можете получить БЕДСТВИЙ !!)
Функция 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); } ?>
Я хочу расширить ответ @alcuadrado с комментариями @Vijit для обработки символических ссылок. Во-первых, используйте getRealPath (). Но тогда, если у вас есть какие-либо символические ссылки, которые являются папками, это не удастся, поскольку он попытается вызвать rmdir по ссылке – так что вам нужна дополнительная проверка.
$it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS); $files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST); foreach($files as $file) { if ($file->isLink()) { unlink($file->getPathname()); } else if ($file->isDir()){ rmdir($file->getPathname()); } else { unlink($file->getPathname()); } } rmdir($dir);
Что-то вроде этого?
function delete_folder($folder) { $glob = glob($folder); foreach ($glob as $g) { if (!is_dir($g)) { unlink($g); } else { delete_folder("$g/*"); rmdir($g); } } }
Удаление всех файлов в папке
array_map('unlink', glob("$directory/*.*"));
Удалить все. * – Файлы в папке (без: "." И "..")
array_map('unlink', array_diff(glob("$directory/.*),array("$directory/.","$directory/..")))
Теперь удалите папку
rmdir($directory)
2 цента, чтобы добавить к ЭТОМУ ответу выше, что отличное BTW
После того, как функция glob (или аналогичная) сканирует / читает каталог, добавьте условие, чтобы проверить, что ответ не пуст, или будет invalid argument supplied for foreach()
предупреждения invalid argument supplied for foreach()
. Так…
if( ! empty( $files ) ) { foreach( $files as $file ) { // do your stuff here... } }
Моя полная функция (как метод объекта):
private function recursiveRemoveDirectory( $directory ) { if( ! is_dir( $directory ) ) { throw new InvalidArgumentException( "$directory must be a directory" ); } if( substr( $directory, strlen( $directory ) - 1, 1 ) != '/' ) { $directory .= '/'; } $files = glob( $directory . "*" ); if( ! empty( $files ) ) { foreach( $files as $file ) { if( is_dir( $file ) ) { $this->recursiveRemoveDirectory( $file ); } else { unlink( $file ); } } } rmdir( $directory ); } // END recursiveRemoveDirectory()
<?php 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); } } ?>
Попробуйте выписать код из php.net
Работайте со мной хорошо
Для окон:
system("rmdir ".escapeshellarg($path) . " /s /q");
Как и решение Playnox, но с элегантным встроенным каталогом:
function delete_directory($dirPath){ if(is_dir($dirPath)){ $objects=new DirectoryIterator($dirPath); foreach ($objects as $object){ if(!$object->isDot()){ if($object->isDir()){ delete_directory($object->getPathname()); }else{ unlink($object->getPathname()); } } } rmdir($dirPath); }else{ throw new Exception(__FUNCTION__.'(dirPath): dirPath is not a directory!'); } }
Я не помню, откуда я скопировал эту функцию, но похоже, что ее нет в списке, и она работает для меня
function rm_rf($path) { if (@is_dir($path) && is_writable($path)) { $dp = opendir($path); while ($ent = readdir($dp)) { if ($ent == '.' || $ent == '..') { continue; } $file = $path . DIRECTORY_SEPARATOR . $ent; if (@is_dir($file)) { rm_rf($file); } elseif (is_writable($file)) { unlink($file); } else { echo $file . "is not writable and cannot be removed. Please fix the permission or select a new path.\n"; } } closedir($dp); return rmdir($path); } else { return @unlink($path); } }
Это мой код, и он работает на 100%. Сначала вы должны удалить все файлы из папки, а затем сами поместить папку. Код не содержит вложенных папок, но вы можете легко включить этот код, чтобы включить также вложенную папку в папке $ _POST.
function delete_folder() { $dirPath = $_POST['dirpath']; $TrackDir=opendir($dirPath); $i = 0; while ($file = readdir($TrackDir)) { if ($file == "." || $file == "..") { } else { $narray[$i]=$file; $i++; } } $count1 = count($narray); if($count1 > 0){ $r=0; while($r < $count1){ $Filename = $narray[$r]; $myFile = $dirPath."/".$Filename; unlink($myFile); $r++; } rmdir($dirPath); }else{ rmdir($dirPath); } closedir($TrackDir); }
Простой и легкий …
$dir ='pathtodir'; if (is_dir($dir)) { foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename) { if ($filename->isDir()) continue; unlink($filename); } rmdir($dir); }
Пример для сервера Linux: exec('rm -f -r ' . $cache_folder . '/*');
Вот решение, которое прекрасно работает:
function unlink_r($from) { if (!file_exists($from)) {return false;} $dir = opendir($from); while (false !== ($file = readdir($dir))) { if ($file == '.' OR $file == '..') {continue;} if (is_dir($from . DIRECTORY_SEPARATOR . $file)) { unlink_r($from . DIRECTORY_SEPARATOR . $file); } else { unlink($from . DIRECTORY_SEPARATOR . $file); } } rmdir($from); closedir($dir); return true; }
Как насчет этого?
function Delete_Directory($Dir) { if(is_dir($Dir)) { $files = glob( $Dir . '*', GLOB_MARK ); //GLOB_MARK adds a slash to directories returned foreach( $files as $file ) { Delete_Directory( $file ); } if(file_exists($Dir)) { rmdir($Dir); } } elseif(is_file($Dir)) { unlink( $Dir ); } }
Refrence: https://paulund.co.uk/php-delete-directory-and-files-in-directory
Вот простое решение
$dirname = $_POST['d']; $folder_handler = dir($dirname); while ($file = $folder_handler->read()) { if ($file == "." || $file == "..") continue; unlink($dirname.'/'.$file); } $folder_handler->close(); rmdir($dirname);
-$dirname = $_POST['d']; $folder_handler = dir($dirname); while ($file = $folder_handler->read()) { if ($file == "." || $file == "..") continue; unlink($dirname.'/'.$file); } $folder_handler->close(); rmdir($dirname);
Независимый от платформы код.
Получил ответ от PHP.net
if(PHP_OS === 'Windows') { exec("rd /s /q {$path}"); } else { exec("rm -rf {$path}"); }