如何删除不为空的目录?

发布于 2024-08-09 01:52:02 字数 77 浏览 2 评论 0原文

我尝试使用 rmdir 删除目录,但收到“目录不为空”消息,因为其中仍有文件。

我可以使用什么函数来删除包含所有文件的目录?

I am trying to remove a directory with rmdir, but I received the 'Directory not empty' message, because it still has files in it.

What function can I use to remove a directory with all the files in it as well?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

一身仙ぐ女味 2024-08-16 01:52:02
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 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);
 }
}
另类 2024-08-16 01:52:02

想不出比这更简单、更有效的方法了

function removeDir($dirname) {
    if (is_dir($dirname)) {
        $dir = new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS);
        foreach (new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST) as $object) {
            if ($object->isFile()) {
                unlink($object);
            } elseif($object->isDir()) {
                rmdir($object);
            } else {
                throw new Exception('Unknown object type: '. $object->getFileName());
            }
        }
        rmdir($dirname); // Now remove myfolder
    } else {
        throw new Exception('This is not a directory');
    }
}


removeDir('./myfolder');

Can't think of an easier and more efficient way to do that than this

function removeDir($dirname) {
    if (is_dir($dirname)) {
        $dir = new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS);
        foreach (new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST) as $object) {
            if ($object->isFile()) {
                unlink($object);
            } elseif($object->isDir()) {
                rmdir($object);
            } else {
                throw new Exception('Unknown object type: '. $object->getFileName());
            }
        }
        rmdir($dirname); // Now remove myfolder
    } else {
        throw new Exception('This is not a directory');
    }
}


removeDir('./myfolder');
会傲 2024-08-16 01:52:02

您始终可以尝试使用系统命令。

如果在 Linux 上使用:rm -rf /dir
如果在 Windows 上使用: rd c:\dir /S /Q

在上面的帖子中 (John Kugelman)我想 PHP 解析器会优化 foreach 中的 scandir 但对我来说使用 似乎是错误的foreach 条件语句中的 scandir
您还可以只执行两个 array_shift 命令来删除 ...,而不是始终在循环中进行检查。

You could always try to use system commands.

If on linux use: rm -rf /dir
If on windows use: rd c:\dir /S /Q

In the post above (John Kugelman) I suppose the PHP parser will optimize that scandir in the foreach but it just seems wrong to me to have the scandir in the foreach condition statement.
You could also just do two array_shift commands to remove the . and .. instead of always checking in the loop.

囚我心虐我身 2024-08-16 01:52:02

我的案例有很多棘手的目录(名称包含特殊字符、深层嵌套等)和隐藏文件,这些文件与其他建议的解决方案一起产生“目录不为空”错误。由于仅 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;
}

My case had quite a few tricky directories (names containing special characters, deep nesting, etc) and hidden files that produced "Directory not empty" errors with other suggested solutions. Since a Unix-only solution was unacceptable, I tested until I arrived at the following solution (which worked well in my case):

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;
}
银河中√捞星星 2024-08-16 01:52:02

这是我使用的:

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

Here what I used:

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);
记忆で 2024-08-16 01:52:02

已经有很多解决方案,还有另一种可能性,使用 PHP 箭头函数使用更少的代码:

function rrmdir(string $directory): bool
{
    array_map(fn (string $file) => is_dir($file) ? rrmdir($file) : unlink($file), glob($directory . '/' . '*'));

    return rmdir($directory);
}

There are plenty of solutions already, still another possibility with less code using PHP arrow function:

function rrmdir(string $directory): bool
{
    array_map(fn (string $file) => is_dir($file) ? rrmdir($file) : unlink($file), glob($directory . '/' . '*'));

    return rmdir($directory);
}
豆芽 2024-08-16 01:52:02

来自 http://php.net/manual/en/function.rmdir.php #91797

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

From http://php.net/manual/en/function.rmdir.php#91797

Glob function doesn't return the hidden files, therefore scandir can be more useful, when trying to delete recursively a tree.

<?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); 
  } 
?>
无可置疑 2024-08-16 01:52:02
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 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); 
} 
中二柚 2024-08-16 01:52:02

使用此功能,您将能够删除任何文件或文件夹

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

With this function, you will be able to delete any file or folder

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);
}
伊面 2024-08-16 01:52:02

我没有到达删除文件夹,因为 PHP 告诉我它不是空的。但确实如此。 Naman 的功能是完成我的功能的好解决方案。这就是我使用的:

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

function deleteDir($dir) {

    foreach(glob($dir . '/' . '*') as $file) {
        if(is_dir($file)){


            deleteDir($file);
        } else {

          unlink($file);
        }
    }
    emptyDir($dir);
    rmdir($dir);
}

因此,要删除目录并递归地删除其内容:

deleteDir($dir);

I didn't arrive to delete a folder because PHP said me it was not empty. But it was. The function by Naman was the good solution to complete mine. So this is what I use :

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

function deleteDir($dir) {

    foreach(glob($dir . '/' . '*') as $file) {
        if(is_dir($file)){


            deleteDir($file);
        } else {

          unlink($file);
        }
    }
    emptyDir($dir);
    rmdir($dir);
}

So, to delete a directory and recursively its content :

deleteDir($dir);
椒妓 2024-08-16 01:52:02

尝试以下方便的功能:

/**
 * 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);
}

Try the following handy function:

/**
 * 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);
}
素罗衫 2024-08-16 01:52:02
array_map('unlink', glob("your/path/*.*"));
rmdir("your/path");
array_map('unlink', glob("your/path/*.*"));
rmdir("your/path");
薄情伤 2024-08-16 01:52:02

没有内置函数可以执行此操作,但请参阅 https://www.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,因此请注意这一点。如果你走那条路我会尝试这样的事情:

function deleteDirectory($dir) {
    system('rm -rf -- ' . escapeshellarg($dir), $retval);
    return $retval == 0; // UNIX commands return zero on success
}

There is no built-in function to do this, but see the comments at the bottom of https://www.php.net/rmdir. A number of commenters posted their own recursive directory deletion functions. You can take your pick from those.

Here's one that looks decent:

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

You could just invoke rm -rf if you want to keep things simple. That does make your script UNIX-only, so beware of that. If you go that route I would try something like:

function deleteDirectory($dir) {
    system('rm -rf -- ' . escapeshellarg($dir), $retval);
    return $retval == 0; // UNIX commands return zero on success
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文