如何在 PHP 中递归删除目录及其全部内容(文件 + 子目录)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3338123/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I recursively delete a directory and its entire contents (files + sub dirs) in PHP?
提问by Itay Moav -Malimovka
How do I delete a directory and its entire contents (files and subdirectories) in PHP?
如何在 PHP 中删除目录及其全部内容(文件和子目录)?
回答by Artefacto
The user-contributed section in the manual page of rmdircontains a decent implementation:
手册页中的用户贡献部分rmdir包含一个不错的实现:
function rrmdir($dir) {
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
if (is_dir($dir. DIRECTORY_SEPARATOR .$object) && !is_link($dir."/".$object))
rrmdir($dir. DIRECTORY_SEPARATOR .$object);
else
unlink($dir. DIRECTORY_SEPARATOR .$object);
}
}
rmdir($dir);
}
}
回答by salathe
Building on The Pixel Developer's comment, a snippet using the SPL might look like:
基于The Pixel Developer 的评论,使用 SPL 的片段可能如下所示:
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($files as $fileinfo) {
$todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
$todo($fileinfo->getRealPath());
}
rmdir($dir);
Note: It does nosanity checking and makes use of the SKIP_DOTS flag introduced with the FilesystemIterator in PHP 5.3.0. Of course, the $todocould be an if/else. The important point is that CHILD_FIRSTis used to iterate over the children (files) first before their parent (folders).
注:它确实没有完整性检查,并利用在PHP 5.3.0与FilesystemIterator推出SKIP_DOTS标志。当然,$todo可以是if/ else。重要的一点是CHILD_FIRST用于在其父级(文件夹)之前首先迭代子级(文件)。
回答by Liko
Deletes all files and folders in the path.
删除路径中的所有文件和文件夹。
function recurseRmdir($dir) {
$files = array_diff(scandir($dir), array('.','..'));
foreach ($files as $file) {
(is_dir("$dir/$file")) ? recurseRmdir("$dir/$file") : unlink("$dir/$file");
}
return rmdir($dir);
}
回答by ankitjaininfo
For *nix you can use a shell_execfor rm -Ror DEL /S folder_namefor Windows.
对于 *nix,您可以使用shell_execforrm -R或DEL /S folder_namefor Windows。
回答by XzaR
<?php
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use SplFileInfo;
# http://stackoverflow.com/a/3352564/283851
# https://gist.github.com/XzaR90/48c6b615be12fa765898
# Forked from https://gist.github.com/mindplay-dk/a4aad91f5a4f1283a5e2
/**
* Recursively delete a directory and all of it's contents - e.g.the equivalent of `rm -r` on the command-line.
* Consistent with `rmdir()` and `unlink()`, an E_WARNING level error will be generated on failure.
*
* @param string $source absolute path to directory or file to delete.
* @param bool $removeOnlyChildren set to true will only remove content inside directory.
*
* @return bool true on success; false on failure
*/
function rrmdir($source, $removeOnlyChildren = false)
{
if(empty($source) || file_exists($source) === false)
{
return false;
}
if(is_file($source) || is_link($source))
{
return unlink($source);
}
$files = new RecursiveIteratorIterator
(
new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);
//$fileinfo as SplFileInfo
foreach($files as $fileinfo)
{
if($fileinfo->isDir())
{
if(rrmdir($fileinfo->getRealPath()) === false)
{
return false;
}
}
else
{
if(unlink($fileinfo->getRealPath()) === false)
{
return false;
}
}
}
if($removeOnlyChildren === false)
{
return rmdir($source);
}
return true;
}
回答by David Newcomb
There is another thread with more examples here: A recursive remove directory function for PHP?
这里还有另一个包含更多示例的线程: A recursive remove directory function for PHP?
If you are using Yii then you can leave it to the framework:
如果你使用 Yii,那么你可以把它留给框架:
CFileHelper::removeDirectory($my_directory);
回答by Programster
'simple' code that works and can be read by a ten year old:
“简单”的代码可以工作并且可以被 10 岁的孩子阅读:
function deleteNonEmptyDir($dir)
{
if (is_dir($dir))
{
$objects = scandir($dir);
foreach ($objects as $object)
{
if ($object != "." && $object != "..")
{
if (filetype($dir . "/" . $object) == "dir")
{
deleteNonEmptyDir($dir . "/" . $object);
}
else
{
unlink($dir . "/" . $object);
}
}
}
reset($objects);
rmdir($dir);
}
}
Please note that all I did was expand/simplify and fix (didn't work for non empty dir) the solution here: In PHP how do I recursively remove all folders that aren't empty?
请注意,我所做的只是扩展/简化和修复(不适用于非空目录)这里的解决方案: 在 PHP 中,我如何递归删除所有非空文件夹?
回答by jave.web
Enhanced @Artefacto 's solution - corrected typos and simplified code, working for both - empty && non-empty directories .
增强了@Arteacto 的解决方案 - 更正了拼写错误并简化了代码,适用于两者 - 空 && 非空目录。
function recursive_rmdir($dir) {
if( is_dir($dir) ) {
$objects = array_diff( scandir($dir), array('..', '.') );
foreach ($objects as $object) {
$objectPath = $dir."/".$object;
if( is_dir($objectPath) )
recursive_rmdir($objectPath);
else
unlink($objectPath);
}
rmdir($dir);
}
}
回答by David Pankov
The 100% working solution
100% 有效的解决方案
public static function rmdir_recursive($directory, $delete_parent = null)
{
$files = glob($directory . '/{,.}[!.,!..]*',GLOB_MARK|GLOB_BRACE);
foreach ($files as $file) {
if (is_dir($file)) {
self::rmdir_recursive($file, 1);
} else {
unlink($file);
}
}
if ($delete_parent) {
rmdir($directory);
}
}
回答by jlh
It seems that all other answers assume the path given to the function is always a directory. This variant works to remove directories as well as single files:
似乎所有其他答案都假定给函数的路径始终是目录。此变体可用于删除目录和单个文件:
/**
* Recursively delete a file or directory. Use with care!
*
* @param string $path
*/
function recursiveRemove($path) {
if (is_dir($path)) {
foreach (scandir($path) as $entry) {
if (!in_array($entry, ['.', '..'])) {
recursiveRemove($path . DIRECTORY_SEPARATOR . $entry);
}
}
rmdir($path);
} else {
unlink($path);
}
}

