Php 是否删除包含文件的目录?

Php 是否删除包含文件的目录?,php,rmdir,Php,Rmdir,我想知道,删除包含所有文件的目录最简单的方法是什么 我使用的是rmdir(PATH.'/'.$value)删除文件夹,但是,如果文件夹中有文件,我就不能删除它。现在至少有两个选项可用 删除文件夹之前,请删除其所有文件和文件夹(这意味着递归!)。以下是一个例子: public static function deleteDir($dirPath) { if (! is_dir($dirPath)) { throw new InvalidArgumentException("

我想知道,删除包含所有文件的目录最简单的方法是什么


我使用的是
rmdir(PATH.'/'.$value)
删除文件夹,但是,如果文件夹中有文件,我就不能删除它。

现在至少有两个选项可用

  • 删除文件夹之前,请删除其所有文件和文件夹(这意味着递归!)。以下是一个例子:

    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,而无需自己实现递归:

    $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);
    
  • 删除包含所有文件的目录最简单的方法是什么


    完成此任务的短函数:

    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 deleteDir($path) {
        if (empty($path)) { 
            return false;
        }
        return is_file($path) ?
                @unlink($path) :
                array_map(__FUNCTION__, glob($path.'/*')) == @rmdir($path);
    }
    

    我更喜欢这样做,因为它在成功时仍然返回TRUE,在失败时仍然返回FALSE,并且它还可以防止出现一个错误,即空路径可能尝试删除“/*”中的所有内容!!:

    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 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()
    (请参阅)的大多数投票评论所示,
    glob()
    函数不会返回隐藏文件
    scandir()
    作为解决该问题的替代方案提供

    这里描述的算法(在我的例子中,它就像一个符咒)是:

    
    
    像这样的东西

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

    这里有一个简单的递归,用于删除源目录(包括该目录)中的所有文件:

    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);
    
    }
    
    函数基于复制目录的递归。您可以在此处找到该函数:

    
    
    您是否试用过php.net中的obove代码

    为我工作很好

    适用于windows:

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

    alcuadrado代码的少量修改-
    glob
    .htaccess
    这样的点上看不到名为的文件,所以我使用scandir,脚本会自动删除-检查
    \uuuuuuuuuu文件

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

    我通常使用此选项删除文件夹中的所有文件:

    array_map('unlink', glob("$dirname/*.*"));
    
    然后你就可以做了

    rmdir($dirname);
    

    与Playnox的解决方案类似,但具有优雅的内置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!');
      }
     }
    

    对我来说最好的解决方案

    my_folder_delete("../path/folder");
    
    代码:

    p、 记住
    不要将空值传递给任何目录删除函数!!!(总是备份它们,否则有一天你可能会遇到灾难!!)

    你可以使用Symfony的():

    但是,我无法使用此方法删除一些复杂的目录结构,因此首先您应该尝试使用它以确保其正常工作


    我可以使用特定于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);
    }
    

    删除文件夹中的所有文件
    数组映射('unlink',glob($directory/*.*)
    删除文件夹中的所有文件(不带“.”和“.”)
    array\u-map('unlink',array\u-diff(glob($directory/*),array($directory/,“$directory/.”))

    现在删除文件夹本身

    rmdir($directory)

    我不记得从何处复制了此函数,但它似乎没有列出,并且对我有效

    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);
        }
    }
    
    那么这个呢:

    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);
    }
    
    简单易懂

    $dir ='pathtodir';
    if (is_dir($dir)) {
      foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename) {
        if ($filename->isDir()) continue;
        unlink($filename);
      }
      rmdir($dir);
    }
    
    2美分添加到上面,这是伟大的顺便说一句

    在glob(或类似)函数扫描/读取目录后,添加一个条件以检查响应是否为空,否则将抛出为foreach()提供的
    无效参数。
    警告。因此

    if( ! empty( $files ) )
    {
        foreach( $files as $file )
        {
            // do your stuff here...
        }
    }
    
    我的全部功能(作为对象方法):


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

    我想在@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);
    

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

    以下是一个完美的解决方案:

    function unlink_r($from) {
        if (!file_exists($from)) {return false;}
        $dir = opendir($from);
        while (false !== ($file = readdir($dir))) {
            if ($file == '.' OR $file == '..') {continue;}
    
            if (is_dir($from . DIRECTORY_SEPARATOR . $file)) {
                unlink_r($from . DIRECTORY_SEPARATOR . $file);
            }
            else {
                unlink($from . DIRECTORY_SEPARATOR . $file);
            }
        }
        rmdir($from);
        closedir($dir);
        return true;
    }
    

    使用DirectoryIterator与前面的答案等效

    function deleteFolder($rootPath)
    {   
        foreach(new DirectoryIterator($rootPath) as $fileToDelete)
        {
            if($fileToDelete->isDot()) continue;
            if ($fileToDelete->isFile())
                unlink($fileToDelete->getPathName());
            if ($fileToDelete->isDir())
                deleteFolder($fileToDelete->getPathName());
        }
    
        rmdir($rootPath);
    }
    
    这个对我很有用:

    function removeDirectory($path) {
        $files = glob($path . '/*');
        foreach ($files as $file) {
            is_dir($file) ? removeDirectory($file) : unlink($file);
        }
        rmdir($path);
        return;
    }
    

    您可以尝试以下操作:

    /*
     * Remove the directory and its content (all files and subdirectories).
     * @param string $dir the directory name
     */
    function rmrf($dir) {
        foreach (glob($dir) as $file) {
            if (is_dir($file)) { 
                rmrf("$file/*");
                rmdir($file);
            } else {
                unlink($file);
            }
        }
    }
    

    您可以尝试这12行简单的代码来删除文件夹或文件夹文件。。。 快乐编码…;):)


    你可以复制YII助手

    $directory(string)-以递归方式删除

    $options(array)-用于删除目录。 有效选项包括: traverseSymlinks:布尔值,表示是否也应遍历指向目录的符号链接。默认值为
    false
    ,表示不会删除符号链接目录的内容。在默认情况下,仅删除符号链接

    public static function removeDirectory($directory,$options=array())
    {
        if(!isset($options['traverseSymlinks']))
            $options['traverseSymlinks']=false;
        $items=glob($directory.DIRECTORY_SEPARATOR.'{,.}*',GLOB_MARK | GLOB_BRACE);
        foreach($items as $item)
        {
            if(basename($item)=='.' || basename($item)=='..')
                continue;
            if(substr($item,-1)==DIRECTORY_SEPARATOR)
            {
                if(!$options['traverseSymlinks'] && is_link(rtrim($item,DIRECTORY_SEPARATOR)))
                    unlink(rtrim($item,DIRECTORY_SEPARATOR));
                else
                    self::removeDirectory($item,$options);
            }
            else
                unlink($item);
        }
        if(is_dir($directory=rtrim($directory,'\\/')))
        {
            if(is_link($directory))
                unlink($directory);
            else
                rmdir($directory);
        }
    }
    

    我不敢相信有30多个答案。在PHP中递归删除一个文件夹可能需要几分钟,具体取决于目录的深度和其中的文件数!您只需一行代码即可完成此操作

    shell_exec(“rm-rf”$dir);


    如果您想删除整个文件系统,请首先确保您的
    $dir
    路径正是您想要的。绝不允许用户输入可以直接删除文件的内容,而不首先对输入进行大量验证。这是基本的编码实践。

    可能重复的yup,在该问题中得到了准确的回答。只是want注意。我创建了多个文件,如果在此过程中出现错误,则需要删除以前创建的文件。创建文件时,忘记使用
    fclose($create_file);
    删除时,得到
    警告:取消链接(created_file.xml):权限在…
    中被拒绝。因此,为了避免此类错误,必须关闭创建的文件。我希望您不是认真的。如果$dir与上述任何代码完全相同,会发生什么情况?请注意,这取决于
    $dir
    的使用方式
    $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 unlink_r($from) {
        if (!file_exists($from)) {return false;}
        $dir = opendir($from);
        while (false !== ($file = readdir($dir))) {
            if ($file == '.' OR $file == '..') {continue;}
    
            if (is_dir($from . DIRECTORY_SEPARATOR . $file)) {
                unlink_r($from . DIRECTORY_SEPARATOR . $file);
            }
            else {
                unlink($from . DIRECTORY_SEPARATOR . $file);
            }
        }
        rmdir($from);
        closedir($dir);
        return true;
    }
    
    function deleteFolder($rootPath)
    {   
        foreach(new DirectoryIterator($rootPath) as $fileToDelete)
        {
            if($fileToDelete->isDot()) continue;
            if ($fileToDelete->isFile())
                unlink($fileToDelete->getPathName());
            if ($fileToDelete->isDir())
                deleteFolder($fileToDelete->getPathName());
        }
    
        rmdir($rootPath);
    }
    
    function removeDirectory($path) {
        $files = glob($path . '/*');
        foreach ($files as $file) {
            is_dir($file) ? removeDirectory($file) : unlink($file);
        }
        rmdir($path);
        return;
    }
    
    /*
     * Remove the directory and its content (all files and subdirectories).
     * @param string $dir the directory name
     */
    function rmrf($dir) {
        foreach (glob($dir) as $file) {
            if (is_dir($file)) { 
                rmrf("$file/*");
                rmdir($file);
            } else {
                unlink($file);
            }
        }
    }
    
    function deleteAll($str) {
        if (is_file($str)) {
            return unlink($str);
        }
        elseif (is_dir($str)) {
            $scan = glob(rtrim($str,'/').'/*');
            foreach($scan as $index=>$path) {
                $this->deleteAll($path);
            }            
            return @rmdir($str);
        }
    }
    
    public static function removeDirectory($directory,$options=array())
    {
        if(!isset($options['traverseSymlinks']))
            $options['traverseSymlinks']=false;
        $items=glob($directory.DIRECTORY_SEPARATOR.'{,.}*',GLOB_MARK | GLOB_BRACE);
        foreach($items as $item)
        {
            if(basename($item)=='.' || basename($item)=='..')
                continue;
            if(substr($item,-1)==DIRECTORY_SEPARATOR)
            {
                if(!$options['traverseSymlinks'] && is_link(rtrim($item,DIRECTORY_SEPARATOR)))
                    unlink(rtrim($item,DIRECTORY_SEPARATOR));
                else
                    self::removeDirectory($item,$options);
            }
            else
                unlink($item);
        }
        if(is_dir($directory=rtrim($directory,'\\/')))
        {
            if(is_link($directory))
                unlink($directory);
            else
                rmdir($directory);
        }
    }