Интересно, что самый простой способ удалить каталог со всеми его файлами в нем?
Я использую rmdir(PATH . '/' . $value);
для удаления папки, однако, если в ней есть файлы, я просто не могу ее удалить.
Интересно, что самый простой способ удалить каталог со всеми его файлами в нем?
Я использую 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);
}
?>
Вы можете использовать файловую систему 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);
}
Здесь у вас есть одна хорошая и простая рекурсия для удаления всех файлов в исходном каталоге, включая этот каталог:
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
Как насчет этого:
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);
}
Функция 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);
}
?>
Я предпочитаю это, потому что он все еще возвращает 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);
}
Лучшее решение для меня
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);
}
}
p.s. ЗАПОМНИТЬ!
не пропускайте ПУСТОЙ ЦЕННОСТИ в любой каталог, удаляющий функции!!! (резервируйте их всегда, иначе в один прекрасный день вы можете получить БЕДСТВИЙ!!)
Litle bit изменить код alcuadrado - glob
не видеть файлы с именем из таких точек, как .htaccess
, поэтому я использую scandir и script удаляет себя - проверьте __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);
}
Я хочу расширить ответ на @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);
Использование DirectoryIterator эквивалент предыдущего ответа...
function deleteFolder($rootPath)
{
foreach(new DirectoryIterator($rootPath) as $fileToDelete)
{
if($fileToDelete->isDot()) continue;
if ($fileToDelete->isFile())
unlink($fileToDelete->getPathName());
if ($fileToDelete->isDir())
deleteFolder($fileToDelete->getPathName());
}
rmdir($rootPath);
}
Этот работает для меня:
function removeDirectory($path) {
$files = glob($path . '/*');
foreach ($files as $file) {
is_dir($file) ? removeDirectory($file) : unlink($file);
}
rmdir($path);
return;
}
Вы можете попробовать следующим образом:
/*
* Remove the directory and its content (all files and subdirectories).
* @param string $dir the directory name
*/
function rmrf($dir) {
foreach (glob($dir) as $file) {
if (is_dir($file)) {
rmrf("$file/*");
rmdir($file);
} else {
unlink($file);
}
}
}
Что-то вроде этого?
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()
. Так что...
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()
Пример для сервера 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;
}
<?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);
}
Как насчет этого?
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 );
}
}
Ссылка: https://paulund.co.uk/php-delete-directory-and-files-in-directory
Если вы не уверены, что заданный путь является каталогом или файлом, вы можете использовать эту функцию для удаления пути
function deletePath($path) {
if(is_file($path)){
unlink($path);
} elseif(is_dir($path)){
$path = (substr($path, -1) !== DIRECTORY_SEPARATOR) ? $path . DIRECTORY_SEPARATOR : $path;
$files = glob($path . '*');
foreach ($files as $file) {
deleteDirPath($file);
}
rmdir($path);
} else {
return false;
}
}