删除包含文件的目录?

我想知道,什么是最简单的方法来删除其中的所有文件的目录?

我正在使用rmdir(PATH . '/' . $value); 删除一个文件夹,但是,如果里面有文件,我根本无法删除它。

目前至less有两个选项。

  1. 删除文件夹之前,删除所有的文件和文件夹(这意味着recursion!)。 这里是一个例子:

     public static function deleteDir($dirPath) { if (! is_dir($dirPath)) { throw new InvalidArgumentException("$dirPath must be a directory"); } if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') { $dirPath .= '/'; } $files = glob($dirPath . '*', GLOB_MARK); foreach ($files as $file) { if (is_dir($file)) { self::deleteDir($file); } else { unlink($file); } } rmdir($dirPath); } 
  2. 如果您使用的是5.2+,则可以使用RecursiveIterator来执行此操作,而无需亲自执行recursion:

     $dir = 'samples' . DIRECTORY_SEPARATOR . 'sampledirtree'; $it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS); $files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST); foreach($files as $file) { if ($file->isDir()){ rmdir($file->getRealPath()); } else { unlink($file->getRealPath()); } } rmdir($dir); 

我通常使用这个来删除文件夹中的所有文件:

 array_map('unlink', glob("$dirname/*.*")); 

然后你可以做

 rmdir($dirname); 

删除一个包含所有文件的目录最简单的方法是什么?

 system("rm -rf ".escapeshellarg($dir)); 

做这个工作的简短function:

 function deleteDir($path) { return is_file($path) ? @unlink($path) : array_map(__FUNCTION__, glob($path.'/*')) == @rmdir($path); } 

我在这样的Utils类中使用它:

 class Utils { public static function deleteDir($path) { $class_func = array(__CLASS__, __FUNCTION__); return is_file($path) ? @unlink($path) : array_map($class_func, glob($path.'/*')) == @rmdir($path); } } 

强大的function带来了巨大的责任 :当你用一个空值调用这个函数时,它将删除以root( / )开头的文件。 作为安全措施,您可以检查path是否为空:

 function deleteDir($path) { if (empty($path)) { return false; } return is_file($path) ? @unlink($path) : array_map(__FUNCTION__, glob($path.'/*')) == @rmdir($path); } 

这是一个较短的版本对我很好

 function deleteDirectory($dirPath) { if (is_dir($dirPath)) { $objects = scandir($dirPath); foreach ($objects as $object) { if ($object != "." && $object !="..") { if (filetype($dirPath . DIRECTORY_SEPARATOR . $object) == "dir") { deleteDirectory($dirPath . DIRECTORY_SEPARATOR . $object); } else { unlink($dirPath . DIRECTORY_SEPARATOR . $object); } } } reset($objects); rmdir($dirPath); } } 

正如在PHP手册页上关于rmdir() (见http://php.net/manual/es/function.rmdir.php )的大多数投票评论中看到的, glob()函数不返回隐藏文件。 scandir()作为解决该问题的替代scheme。

那里描述的algorithm(在我的情况下就像一个魅力工作)是:

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

在这里,你有一个很好的简单的recursion来删除源目录中的所有文件,包括该目录:

 function delete_dir($src) { $dir = opendir($src); while(false !== ( $file = readdir($dir)) ) { if (( $file != '.' ) && ( $file != '..' )) { if ( is_dir($src . '/' . $file) ) { delete_dir($src . '/' . $file); } else { unlink($src . '/' . $file); } } } closedir($dir); rmdir($src); } 

函数是基于复制目录的recursion。 你可以在这里find这个function: 使用PHP将目录的全部内容复制到另一个目录

您可以使用Symfony的文件系统 ( 代码 ):

 // composer require symfony/filesystem use Symfony\Component\Filesystem\Filesystem; (new Filesystem)->remove($dir); 

但是,我不能用这种方法删除一些复杂的目录结构,所以首先你应该尝试确保它正常工作。

我可以使用Windows特定的实现来删除上述目录结构:

 $dir = strtr($dir, '/', '\\'); // quotes are important, otherwise one could // delete "foo" instead of "foo bar" system('RMDIR /S /Q "'.$dir.'"'); 

为了完整起见,这里有一个旧的代码:

 function xrmdir($dir) { $items = scandir($dir); foreach ($items as $item) { if ($item === '.' || $item === '..') { continue; } $path = $dir.'/'.$item; if (is_dir($path)) { xrmdir($path); } else { unlink($path); } } rmdir($dir); } 

我更喜欢这样做,因为它在成功时仍然返回TRUE,在失败时返回FALSE,并且还避免了一个空path可能试图从'/ *'!!中删除所有内容的错误:

 function deleteDir($path) { return !empty($path) && is_file($path) ? @unlink($path) : (array_reduce(glob($path.'/*'), function ($r, $i) { return $r && deleteDir($i); }, TRUE)) && @rmdir($path); } 

那这个呢:

 function recursiveDelete($dirPath, $deleteParent = true){ foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dirPath, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $path) { $path->isFile() ? unlink($path->getPathname()) : rmdir($path->getPathname()); } if($deleteParent) rmdir($dirPath); } 

点燃位修改alcuadrado的代码 – glob不会看到像.htaccess这样的点名称的文件,所以我使用scandir和脚本删除自己 – 检查__FILE__

 function deleteDir($dirPath) { if (!is_dir($dirPath)) { throw new InvalidArgumentException("$dirPath must be a directory"); } if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') { $dirPath .= '/'; } $files = scandir($dirPath); foreach ($files as $file) { if ($file === '.' || $file === '..') continue; if (is_dir($dirPath.$file)) { deleteDir($dirPath.$file); } else { if ($dirPath.$file !== __FILE__) { unlink($dirPath.$file); } } } rmdir($dirPath); } 

对我来说最好的解决scheme

 my_folder_delete("../path/folder"); 

码:

 function my_folder_delete($path) { if(!empty($path) && is_dir($path) ){ $dir = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS); //upper dirs are not included,otherwise DISASTER HAPPENS :) $files = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST); foreach ($files as $f) {if (is_file($f)) {unlink($f);} else {$empty_dirs[] = $f;} } if (!empty($empty_dirs)) {foreach ($empty_dirs as $eachDir) {rmdir($eachDir);}} rmdir($path); } } 

ps记得!
不要将EMPTY VALUES传递给任何目录删除function!!! (总是备份它们,否则有一天你会得到灾难!!)

Glob函数不会返回隐藏的文件,因此在尝试recursion删除树时,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); } ?> 

我想扩展@alcuadrado的回答@Vijit处理符号链接的评论。 首先,使用getRealPath()。 但是,如果你有任何符号链接是文件夹,它将会失败,因为它会尝试在链接上调用rmdir – 所以你需要额外的检查。

 $it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS); $files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST); foreach($files as $file) { if ($file->isLink()) { unlink($file->getPathname()); } else if ($file->isDir()){ rmdir($file->getPathname()); } else { unlink($file->getPathname()); } } rmdir($dir); 

像这样的东西?

 function delete_folder($folder) { $glob = glob($folder); foreach ($glob as $g) { if (!is_dir($g)) { unlink($g); } else { delete_folder("$g/*"); rmdir($g); } } } 

删除文件夹中的所有文件
array_map('unlink', glob("$directory/*.*"));
全部删除。* – 文件夹中的文件(不包含“。”和“..”)
array_map('unlink', array_diff(glob("$directory/.*),array("$directory/.","$directory/..")))
现在删除文件夹本身
rmdir($directory)

2美分添加到这个答案上面,这是很好的顺便说一句

在glob(或类似的)函数扫描/读取目录之后,添加一个条件来检查响应是否为空,或者invalid argument supplied for foreach()警告invalid argument supplied for foreach()invalid argument supplied for foreach()将被抛出。 所以…

 if( ! empty( $files ) ) { foreach( $files as $file ) { // do your stuff here... } } 

我的全部function(作为对象方法):

  private function recursiveRemoveDirectory( $directory ) { if( ! is_dir( $directory ) ) { throw new InvalidArgumentException( "$directory must be a directory" ); } if( substr( $directory, strlen( $directory ) - 1, 1 ) != '/' ) { $directory .= '/'; } $files = glob( $directory . "*" ); if( ! empty( $files ) ) { foreach( $files as $file ) { if( is_dir( $file ) ) { $this->recursiveRemoveDirectory( $file ); } else { unlink( $file ); } } } rmdir( $directory ); } // END recursiveRemoveDirectory() 
 <?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的obove代码

为我工作好

对于Windows:

 system("rmdir ".escapeshellarg($path) . " /s /q"); 

像Playnox的解决scheme,但与优雅的内置DirectoryIterator:

 function delete_directory($dirPath){ if(is_dir($dirPath)){ $objects=new DirectoryIterator($dirPath); foreach ($objects as $object){ if(!$object->isDot()){ if($object->isDir()){ delete_directory($object->getPathname()); }else{ unlink($object->getPathname()); } } } rmdir($dirPath); }else{ throw new Exception(__FUNCTION__.'(dirPath): dirPath is not a directory!'); } } 

我不记得从哪里复制这个function,但它看起来没有列出,它是为我工作

 function rm_rf($path) { if (@is_dir($path) && is_writable($path)) { $dp = opendir($path); while ($ent = readdir($dp)) { if ($ent == '.' || $ent == '..') { continue; } $file = $path . DIRECTORY_SEPARATOR . $ent; if (@is_dir($file)) { rm_rf($file); } elseif (is_writable($file)) { unlink($file); } else { echo $file . "is not writable and cannot be removed. Please fix the permission or select a new path.\n"; } } closedir($dp); return rmdir($path); } else { return @unlink($path); } } 

这是我的代码,它工作100%。 首先,你必须删除文件夹中的所有文件,然后将其自身文件夹。 代码不包含子文件夹,但是您可以轻松地使用此代码来包含$ _POST文件夹的子文件夹。

  function delete_folder() { $dirPath = $_POST['dirpath']; $TrackDir=opendir($dirPath); $i = 0; while ($file = readdir($TrackDir)) { if ($file == "." || $file == "..") { } else { $narray[$i]=$file; $i++; } } $count1 = count($narray); if($count1 > 0){ $r=0; while($r < $count1){ $Filename = $narray[$r]; $myFile = $dirPath."/".$Filename; unlink($myFile); $r++; } rmdir($dirPath); }else{ rmdir($dirPath); } closedir($TrackDir); } 

简单和容易…

 $dir ='pathtodir'; if (is_dir($dir)) { foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename) { if ($filename->isDir()) continue; unlink($filename); } rmdir($dir); } 

Linux服务器示例: exec('rm -f -r ' . $cache_folder . '/*');

这是一个简单的解决scheme

 $dirname = $_POST['d']; $folder_handler = dir($dirname); while ($file = $folder_handler->read()) { if ($file == "." || $file == "..") continue; unlink($dirname.'/'.$file); } $folder_handler->close(); rmdir($dirname); 

独立于平台的代码

从PHP.net取得了答案

 if(PHP_OS === 'Windows') { exec("rd /s /q {$path}"); } else { exec("rm -rf {$path}"); }