如何删除非空目录?

时间:2009-10-31 08:22:05

标签: php directory

我正在尝试使用rmdir删除目录,但我收到了“目录不为空”消息,因为它仍然包含文件。

我可以用什么功能删除包含其中所有文件的目录?

10 个答案:

答案 0 :(得分:97)

没有内置函数可以执行此操作,但请参阅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
}

答案 1 :(得分:7)

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

答案 2 :(得分:6)

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

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

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

答案 3 :(得分:3)

我在这里使用的是:

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

答案 4 :(得分:3)

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

答案 5 :(得分:2)

无法想到比这更简单,更有效的方法

<?php
    $dirname = './myfolder';
    if (is_dir($dirname)) {
        $dir = new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS);
        foreach (new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST ) as $filename => $file) {
            if (is_file($filename))
                unlink($filename);
            else
                rmdir($filename);
        }
        rmdir($dirname); // Now remove myfolder
    }
?>

答案 6 :(得分:2)

我没有删除文件夹,因为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);

答案 7 :(得分:1)

尝试以下方便的功能:

DateTime

答案 8 :(得分:1)

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

<jaxrs:schemaLocations>
    <jaxrs:schemaLocation>classpath:schema1.xsd</jaxrs:schemaLocation>
    <jaxrs:schemaLocation>classpath:schema2.xsd</jaxrs:schemaLocation>
</jaxrs:schemaLocations>

答案 9 :(得分:1)

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