代码之家  ›  专栏  ›  技术社区  ›  Itay Moav -Malimovka

如何在PHP中递归删除目录及其全部内容(文件+子目录)?

  •  115
  • Itay Moav -Malimovka  · 技术社区  · 14 年前

    如何在PHP中删除目录及其全部内容(文件和子目录)?

    20 回复  |  直到 6 年前
        1
  •  177
  •   chaos    9 年前

    您试过手册第页的第一个注释吗? rmdir ?

     function rrmdir($dir) { 
       if (is_dir($dir)) { 
         $objects = scandir($dir); 
         foreach ($objects as $object) { 
           if ($object != "." && $object != "..") { 
             if (is_dir($dir."/".$object))
               rrmdir($dir."/".$object);
             else
               unlink($dir."/".$object); 
           } 
         }
         rmdir($dir); 
       } 
     }
    
        2
  •  104
  •   Community CDub    7 年前

    建立在 The Pixel Developer's comment ,使用SPL的代码段可能如下所示:

    $files = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
        RecursiveIteratorIterator::CHILD_FIRST
    );
    
    foreach ($files as $fileinfo) {
        $todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
        $todo($fileinfo->getRealPath());
    }
    
    rmdir($dir);
    

    注:确实如此 健全性检查并使用php 5.3.0中的文件系统迭代器引入的skip_dots标志。当然, $todo 可以是一个 if / else . 重要的是 CHILD_FIRST 用于在子级(文件)的父级(文件夹)之前对其进行迭代。

        3
  •  14
  •   Liko    11 年前

    删除路径中的所有文件和文件夹。

    function recurseRmdir($dir) {
      $files = array_diff(scandir($dir), array('.','..'));
      foreach ($files as $file) {
        (is_dir("$dir/$file")) ? recurseRmdir("$dir/$file") : unlink("$dir/$file");
      }
      return rmdir($dir);
    }
    
        4
  •  13
  •   Joshua Moore    10 年前

    对于*nix,您可以使用 shell_exec 对于 rm -R DEL /S folder_name 对于Windows。

        5
  •  5
  •   Community CDub    7 年前

    这里还有另一个包含更多示例的线程: A recursive remove directory function for PHP?

    如果您使用的是yii,那么您可以将其留在框架中:

    CFileHelper::removeDirectory($my_directory);
    
        6
  •  5
  •   XzaR    9 年前
    <?php
    
    use RecursiveDirectoryIterator;
    use RecursiveIteratorIterator;
    use SplFileInfo;
    
    # http://stackoverflow.com/a/3352564/283851
    # https://gist.github.com/XzaR90/48c6b615be12fa765898
    
    # Forked from https://gist.github.com/mindplay-dk/a4aad91f5a4f1283a5e2
    
    /**
     * Recursively delete a directory and all of it's contents - e.g.the equivalent of `rm -r` on the command-line.
     * Consistent with `rmdir()` and `unlink()`, an E_WARNING level error will be generated on failure.
     *
     * @param string $source absolute path to directory or file to delete.
     * @param bool   $removeOnlyChildren set to true will only remove content inside directory.
     *
     * @return bool true on success; false on failure
     */
    function rrmdir($source, $removeOnlyChildren = false)
    {
        if(empty($source) || file_exists($source) === false)
        {
            return false;
        }
    
        if(is_file($source) || is_link($source))
        {
            return unlink($source);
        }
    
        $files = new RecursiveIteratorIterator
        (
            new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
            RecursiveIteratorIterator::CHILD_FIRST
        );
    
        //$fileinfo as SplFileInfo
        foreach($files as $fileinfo)
        {
            if($fileinfo->isDir())
            {
                if(rrmdir($fileinfo->getRealPath()) === false)
                {
                    return false;
                }
            }
            else
            {
                if(unlink($fileinfo->getRealPath()) === false)
                {
                    return false;
                }
            }
        }
    
        if($removeOnlyChildren === false)
        {
            return rmdir($source);
        }
    
        return true;
    }
    
        7
  •  1
  •   Community CDub    7 年前

    “简单”代码,10岁的孩子可以阅读:

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

    请注意,我所做的只是扩展/简化和修复(不适用于非空目录)这里的解决方案: In PHP how do I recursively remove all folders that aren't empty?

        8
  •  1
  •   jave.web    9 年前

    增强了@artefactor的解决方案—更正了拼写错误和简化的代码,同时适用于空目录和非空目录。

      function recursive_rmdir($dir) { 
        if( is_dir($dir) ) { 
          $objects = array_diff( scandir($dir), array('..', '.') );
          foreach ($objects as $object) { 
            $objectPath = $dir."/".$object;
            if( is_dir($objectPath) )
              recursive_rmdir($objectPath);
            else
              unlink($objectPath); 
          } 
          rmdir($dir); 
        } 
      }
    
        9
  •  0
  •   Kerem    12 年前

    像这样?

    function delete_folder($folder) {
        $glob = glob($folder);
        foreach ($glob as $g) {
            if (!is_dir($g)) {
                unlink($g);
            } else {
                delete_folder("$g/*");
                rmdir($g);
            }
        }
    }
    
        10
  •  0
  •   Tofeeq    9 年前

    unlink函数通过确保不删除脚本本身,递归地删除给定路径中的所有文件夹和文件。

    function unlinkr($dir, $pattern = "*") {
        // find all files and folders matching pattern
        $files = glob($dir . "/$pattern"); 
    
        //interate thorugh the files and folders
        foreach($files as $file){ 
        //if it is a directory then re-call unlinkr function to delete files inside this directory     
            if (is_dir($file) and !in_array($file, array('..', '.')))  {
                echo "<p>opening directory $file </p>";
                unlinkr($file, $pattern);
                //remove the directory itself
                echo "<p> deleting directory $file </p>";
                rmdir($file);
            } else if(is_file($file) and ($file != __FILE__)) {
                // make sure you don't delete the current script
                echo "<p>deleting file $file </p>";
                unlink($file); 
            }
        }
    }
    

    如果要删除放置此脚本的所有文件和文件夹,请按以下方式调用它

    //get current working directory
    $dir = getcwd();
    unlinkr($dir);
    

    如果只想删除php文件,请按以下方式调用它

    unlinkr($dir, "*.php");
    

    您也可以使用任何其他路径删除文件

    unlinkr("/home/user/temp");
    

    这将删除home/user/temp目录中的所有文件。

        11
  •  0
  •   Alin Razvan    7 年前

    一旦你完成了测试, 移除γ 未链接 γRMIDR 在班里。

    <?php 
    class RMRFiles {
    
            function __construct(){
            }
    
        public function recScan( $mainDir, $allData = array() )
        {
    
        // hide files
        $hidefiles = array(
        ".",
        "..") ;
    
        //start reading directory
        $dirContent = scandir( $mainDir ) ;
    
            //cycle through
            foreach ( $dirContent as $key => $content )
            {
                $path = $mainDir . '/' . $content ;
    
                // if is readable / file
                if ( ! in_array( $content, $hidefiles ) )
                {
                if ( is_file( $path ) && is_readable( $path ) )
                {
                #delete files within directory
                #unlink($path);
                $allData['unlink'][] = $path ;
                }
    
                // if is readable / directory
                else
                if ( is_dir( $path ) && is_readable( $path ) )
                {
                /*recursive*/
                $allData = $this->recScan( $path, $allData ) ;
    
                #finally remove directory
                $allData['rmdir'][]=$path;
                #rmdir($path);
                }
                }
            }
    
        return $allData ;
    
        }
    
    }
    
    header("Content-Type: text/plain");
    
    /* Get absolute path of the running script 
    Ex : /home/user/public_html/   */
    define('ABPATH', dirname(__file__) . '/'); 
    
    /* The folder where we store cache files 
    Ex: /home/user/public_html/var/cache   */
    define('STOREDIR','var/cache'); 
    
    $rmrf = new RMRFiles();
    #here we delete folder content files & directories
    print_r($rmrf->recScan(ABPATH.STOREDIR));
    #finally delete scanned directory ? 
    #rmdir(ABPATH.STOREDIR);
    
    ?>
    
        12
  •  0
  •   Nkc    7 年前
    <?php
    
    /**
     * code by Nk (nk.have.a@gmail.com)
     */
    
    class filesystem
    {
        public static function remove($path)
        {
            return is_dir($path) ? rmdir($path) : unlink($path);
        }
    
        public static function normalizePath($path)
        {
            return $path.(is_dir($path) && !preg_match('@/$@', $path) ? '/' : '');      
        }
    
        public static function rscandir($dir, $sort = SCANDIR_SORT_ASCENDING)
        {
            $results = array();
    
            if(!is_dir($dir))
            return $results;
    
            $dir = self::normalizePath($dir);
    
            $objects = scandir($dir, $sort);
    
            foreach($objects as $object)
            if($object != '.' && $object != '..')
            {
                if(is_dir($dir.$object))
                $results = array_merge($results, self::rscandir($dir.$object, $sort));
                else
                array_push($results, $dir.$object);
            }
    
            array_push($results, $dir);
    
            return $results;
        }
    
        public static function rrmdir($dir)
        {
            $files = self::rscandir($dir);
    
            foreach($files as $file)
            self::remove($file);
    
            return !file_exists($dir);
        }
    }
    
    ?>
    

    PHP:

    <?php
    
    /* include.. */
    
    filesystem::rrmdir('/var/log');
    filesystem::rrmdir('./cache');
    
    ?>
    
        13
  •  0
  •   David Pankov    6 年前

    100%工作溶液

    public static function rmdir_recursive($directory, $delete_parent = null)
      {
        $files = glob($directory . '/{,.}[!.,!..]*',GLOB_MARK|GLOB_BRACE);
        foreach ($files as $file) {
          if (is_dir($file)) {
            self::rmdir_recursive($file, 1);
          } else {
            unlink($file);
          }
        }
        if ($delete_parent) {
          rmdir($directory);
        }
      }
    
        14
  •  0
  •   jlh    6 年前

    似乎所有其他答案都假定给函数的路径总是一个目录。此变量用于删除目录和单个文件:

    /**
     * Recursively delete a file or directory.  Use with care!
     *
     * @param string $path
     */
    function recursiveRemove($path) {
        if (is_dir($path)) {
            foreach (scandir($path) as $entry) {
                if (!in_array($entry, ['.', '..'])) {
                    recursiveRemove($path . DIRECTORY_SEPARATOR . $entry);
                }
            }
            rmdir($path);
        } else {
            unlink($path);
        }
    }
    
        15
  •  -1
  •   Chicna    10 年前

    我只是根据StackOverflow的讨论编写了这段代码。我还没有在Linux环境上测试。这样做是为了完全删除一个文件或目录:

    function splRm(SplFileInfo $i)
    {
        $path = $i->getRealPath();
    
        if ($i->isDir()) {
            echo 'D - ' . $path . '<br />';
            rmdir($path);
        } elseif($i->isFile()) {
            echo 'F - ' . $path . '<br />';
            unlink($path);
        }
    }
    
    function splRrm(SplFileInfo $j)
    {
        $path = $j->getRealPath();
    
        if ($j->isDir()) {
            $rdi = new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS);
            $rii = new RecursiveIteratorIterator($rdi, RecursiveIteratorIterator::CHILD_FIRST);
            foreach ($rii as $i) {
                splRm($i);
            }
        }
        splRm($j);
    
    }
    
    splRrm(new SplFileInfo(__DIR__.'/../dirOrFileName'));
    
        16
  •  -1
  •   D3F4ULT    10 年前
    function rmdir_recursive( $dirname ) {
    
        /**
         * FilesystemIterator and SKIP_DOTS
         */
    
        if ( class_exists( 'FilesystemIterator' ) && defined( 'FilesystemIterator::SKIP_DOTS' ) ) {
    
            if ( !is_dir( $dirname ) ) {
                return false;
            }
    
            foreach( new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dirname, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::CHILD_FIRST ) as $path ) {
                $path->isDir() ? rmdir( $path->getPathname() ) : unlink( $path->getRealPath() );
            }
    
            return rmdir( $dirname );
    
        }
    
        /**
         * RecursiveDirectoryIterator and SKIP_DOTS
         */
    
        if ( class_exists( 'RecursiveDirectoryIterator' ) && defined( 'RecursiveDirectoryIterator::SKIP_DOTS' ) ) {
    
            if ( !is_dir( $dirname ) ) {
                return false;
            }
    
            foreach( new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dirname, RecursiveDirectoryIterator::SKIP_DOTS ), RecursiveIteratorIterator::CHILD_FIRST ) as $path ) {
                $path->isDir() ? rmdir( $path->getPathname() ) : unlink( $path->getRealPath() );
            }
    
            return rmdir( $dirname );
    
        }
    
        /**
         * RecursiveIteratorIterator and RecursiveDirectoryIterator
         */
    
        if ( class_exists( 'RecursiveIteratorIterator' ) && class_exists( 'RecursiveDirectoryIterator' ) ) {
    
            if ( !is_dir( $dirname ) ) {
                return false;
            }
    
            foreach( new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dirname ), RecursiveIteratorIterator::CHILD_FIRST ) as $path ) {
                if ( in_array( $path->getFilename(), array( '.', '..' ) ) ) {
                    continue;
                }
                $path->isDir() ? rmdir( $path->getPathname() ) : unlink( $path->getRealPath() );
            }
    
            return rmdir( $dirname );
    
        }
    
        /**
         * Scandir Recursive
         */
    
        if ( !is_dir( $dirname ) ) {
            return false;
        }
    
        $objects = scandir( $dirname );
    
        foreach ( $objects as $object ) {
            if ( $object === '.' || $object === '..' ) {
                continue;
            }
            filetype( $dirname . DIRECTORY_SEPARATOR . $object ) === 'dir' ? rmdir_recursive( $dirname . DIRECTORY_SEPARATOR . $object ) : unlink( $dirname . DIRECTORY_SEPARATOR . $object );
        }
    
        reset( $objects );
        rmdir( $dirname );
    
        return !is_dir( $dirname );
    
    }
    
        17
  •  -1
  •   Danijel    10 年前

    实例与 glob() 功能。它将递归删除所有文件和文件夹,包括以点开头的文件。

    delete_all( 'folder' );
    
    function delete_all( $item ) {
        if ( is_dir( $item ) ) {
            array_map( 'delete_all', array_diff( glob( "$item/{,.}*", GLOB_BRACE ), array( "$item/.", "$item/.." ) ) );
            rmdir( $item );
        } else {
            unlink( $item );
        }
    };
    
        18
  •  -1
  •   Vladislav Rastrusny    9 年前

    修改了@xzar解决方案的变体。当从文件夹中删除所有文件时,它会删除空文件夹,并抛出异常,而不是在出错时返回false。

    function recursivelyRemoveDirectory($source, $removeOnlyChildren = true)
    {
        if (empty($source) || file_exists($source) === false) {
            throw new Exception("File does not exist: '$source'");
        }
    
        if (is_file($source) || is_link($source)) {
            if (false === unlink($source)) {
                throw new Exception("Cannot delete file '$source'");
            }
        }
    
        $files = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
            RecursiveIteratorIterator::CHILD_FIRST
        );
    
        foreach ($files as $fileInfo) {
            /** @var SplFileInfo $fileInfo */
            if ($fileInfo->isDir()) {
                if ($this->recursivelyRemoveDirectory($fileInfo->getRealPath()) === false) {
                    throw new Exception("Failed to remove directory '{$fileInfo->getRealPath()}'");
                }
                if (false === rmdir($fileInfo->getRealPath())) {
                    throw new Exception("Failed to remove empty directory '{$fileInfo->getRealPath()}'");
                }
            } else {
                if (unlink($fileInfo->getRealPath()) === false) {
                    throw new Exception("Failed to remove file '{$fileInfo->getRealPath()}'");
                }
            }
        }
    
        if ($removeOnlyChildren === false) {
            if (false === rmdir($source)) {
                throw new Exception("Cannot remove directory '$source'");
            }
        }
    }
    
        19
  •  -1
  •   Hamed    8 年前

    我用这个代码…

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

    或者这个…

    <?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); 
      } 
    ?>
    
        20
  •  -1
  •   Illia Yaremchuk    8 年前
    function deltree_cat($folder)
    {
        if (is_dir($folder))
        {
                 $handle = opendir($folder);
                 while ($subfile = readdir($handle))
                 {
                         if ($subfile == '.' or $subfile == '..') continue;
                         if (is_file($subfile)) unlink("{$folder}/{$subfile}");
                         else deltree_cat("{$folder}/{$subfile}");
                 }
                 closedir($handle);
                 rmdir ($folder);
         }
         else
         {
            unlink($folder);
         }
    }
    
    推荐文章