删除包含文件的目录?
我想知道,什么是最简单的方法来删除其中的所有文件的目录?
我正在使用rmdir(PATH . '/' . $value);
删除一个文件夹,但是,如果里面有文件,我根本无法删除它。
目前至less有两个选项。
-
删除文件夹之前,删除所有的文件和文件夹(这意味着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); }
-
如果您使用的是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}"); }