使用php删除所有文件、文件夹及其子文件夹

23

我需要一个能够删除整个目录及其所有子文件夹、文件等的脚本。我之前在互联网上找到了这个函数,但它并没有完全起作用。

function deleteFile($dir) {
    if(substr($dir, strlen($dir)-1, 1) != '/') { 
        $dir .= '/'; 
    }
    if($handle = opendir($dir)) { 
        while($obj = readdir($handle)) { 
            if($obj != '.' && $obj != '..') { 
                if(is_dir($dir.$obj)) { 
                    if(!deleteFile($dir.$obj)) {
                        echo $dir.$obj."<br />";
                        return false;
                    }
                }
                elseif(is_file($dir.$obj)) { 
                    if(!unlink($dir.$obj)) {
                        echo $dir.$obj."<br />";
                        return false;
                    }
                }
            }
        }
        closedir($handle); 
        if(!@rmdir($dir)) {
            echo $dir.'<br />';
            return false;
        }
        return true;
    }
    return true;
}

我正在使用未打包的PrestaShop存档进行测试,尝试删除存档解压缩的文件夹,但不成功。

/home/***/public_html/prestashop/img/p/3/
/home/***/public_html/prestashop/img/p/3
/home/***/public_html/prestashop/img/p
/home/***/public_html/prestashop/img

这些是问题文件夹。起初我想:“可能是文件的chmod权限有问题”,但当我测试了所有文件的chmod权限755(之后是777)时,结果还是一样。

5个回答

82
<?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的评论中尝试上述代码

对我来说运行得很好


这是一个非常好的例子。它可以删除文件和子文件夹。 - Amir Md Amiruzzaman
5
很好的回答,唐纳德。我知道对大多数人来说这很明显,但我认为需要说明一下:在使用此功能(或页面上的任何其他功能)时一定要非常小心。如果您输入错误的参数,它就会(并且会)清除您整个网站的内容。 - Jamie G
有没有办法检测到它成功删除了文件夹?比如它返回true? - MeetMahPuppy
请查看http://php.net/manual/zh/function.rmdir.php rmdir() 返回布尔值...因此您可以使用它。 - donald123
为什么我会得到以下错误:致命错误:未捕获的错误:调用未定义的函数 rrmdir()? - Björn C

10
function delete_files($dir) { 
  foreach(glob($dir . '/*') as $file) { 
    if(is_dir($file)) delete_files($file); else unlink($file); 
  } rmdir($dir); 
}

3
加入一些文本,你至少应该说点什么,而不只是粘贴代码。甚至一个简单的“This should do the trick:”也可以。 - sashoalm
如果初始文件夹不正确,glob()会返回false并显示错误。最好在第一条指令中测试'if is_dir($dir)',成功则返回true,否则返回false。无论如何,它都会考虑每个条目。如果是一个目录,则使用递归调用'delete_file'删除它;否则它是一个文件,并用unlink()删除。最后,$dir为空,因此可以使用'rmdir'删除它。 - Fil

7
您可以使用更加简洁的方法来进行递归删除目录。
示例代码如下:
function recursiveRemove($dir) {
    $structure = glob(rtrim($dir, "/").'/*');
    if (is_array($structure)) {
        foreach($structure as $file) {
            if (is_dir($file)) recursiveRemove($file);
            elseif (is_file($file)) unlink($file);
        }
    }
    rmdir($dir);
}

使用方法:

recursiveRemove("test/dir/");

3
使用 system() 方法是最简单和最好的方法。
$dir = dirname ( "/log" );
if ($handle = opendir($dir)) {
    while (( $file = readdir($handle)) !== false ) {
        if ($file != "." && $file != "..") {
            system("rm -rf ".escapeshellarg($dir.'/'.$file));
        }
    }
}
closedir($handle);

1
如果您无法访问shell(对于许多托管服务而言),我认为您无法使用“system”方法。 - Fil

1
/**
 * Deletes a directory and all files and folders under it
 * @return Null
 * @param $dir String Directory Path
 */
function rmdir_files($dir) {
 $dh = opendir($dir);
 if ($dh) {
  while($file = readdir($dh)) {
   if (!in_array($file, array('.', '..'))) {
    if (is_file($dir.$file)) {
     unlink($dir.$file);
    }
    else if (is_dir($dir.$file)) {
     rmdir_files($dir.$file);
    }
   }
  }
  rmdir($dir);
 }
}

这是同一个函数,但有很多错误 :) - user546774
不要因为它对我有效就说它没有错误,但它是一个非常危险的函数。 - jit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接