2009-10-31 118 views
34

我试图删除rmdir目录,但我收到了“目录不为空”的消息,因为它仍然包含文件。如何删除非空的目录?

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

+0

可能的复制(文件+子dirs)在PHP?](http://stackoverflow.com/questions/3338123/how-do-i-recursively-delete-a-directory-and-its-entire-contents-files-sub-dir) – MaxiWheat 2016-01-29 13:19:54

回答

78

没有内置函数可以做到这一点,但请参阅http://us3.php.net/rmdir底部的注释。许多评论者发布了自己的递归目录删除功能。你可以从中挑选。

这里的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); 
} 

编辑:你可以只调用rm -rf如果你想使事情变得简单。这确实会使你的脚本成为纯UNIX,所以要小心这一点。如果你走这条路线,我会尝试这样的:

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

谈到PHP,**总是**检查在线手册和评论。它通常保证某人先遇到问题并在那里评论。 – 2009-10-31 08:29:01

+0

我选了这个:$ path =“/ path/to/empty”; $ cmd =“rm -rf $ path”; '$ cmd';那有什么不对吗? – zeckdude 2009-10-31 08:34:33

+2

+1 for escapeshellarg()为了安全 – namespaceform 2009-10-31 09:23:34

5

你可以随时尝试使用系统命令。

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

在后上方(John Kugelman)我想PHP解析器将优化在foreach是SCANDIR但它只是似乎是错误的我有条件语句中的scandir中的foreach
您也可以只执行两个array_shift命令来删除...而不是始终检查循环。

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

下面是我用:

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

尝试以下几种实用的功能:

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

有了这个功能,你就可以删除任何文件或文件夹

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

我的情况有很多棘手的目录(不适用包含特殊字符的mes,深层嵌套等)以及使用其他建议的解决方案产生“目录非空”错误的隐藏文件。由于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; 
} 
的[如何递归删除目录及其全部内容
+0

为了扩大对preg_replace的需求,这是必要的,因为一些目录(带有特殊字符)会省略明显存在的子目录。我在php中发现了注释中的preg_replace注释。net()的文档,其他人在同一个问题上挣扎了几个小时。 – 2016-05-09 20:46:11

+0

这是唯一一个可以解决我的问题+1,谢谢 – Franco 2016-06-20 10:46:33