2010-07-26 114 views

回答

137

您是否尝试过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); 
    } 
} 
+1

@Pixel开发人员 - 我添加了[答案](http://stackoverflow.com/questions/3338123/how-do-i-recursively-delete-a-directory-and-its-全内容文件子目录/ 3352564#3352564)。 – salathe 2010-07-28 11:58:51

+2

查看有人给我的相同问题的解决方案:glob似乎工作更好:http://stackoverflow.com/questions/11267086/php-unlink-all-files-withing-a-directory-and-then-deleting -that-directory – 2012-08-10 17:09:53

+0

谢谢你的回答,但reset()在这里没用,你应该使用is_dir();-)(就像你在第2行那样)。 – Loenix 2014-04-30 12:39:44

13

对于* nix中您可以使用rm -R为Windows shell_execDEL /S folder_name

+13

不会在windows上工作 – Gordon 2010-07-27 07:00:52

+2

如何为Windows的DEL/S文件夹名称 – ankitjaininfo 2010-10-21 08:50:02

+0

如果您有安全意识,这不是一件好事 – WiR3D 2016-03-14 14:50:50

90

大厦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与FilesystemIterator推出SKIP_DOTS标志。当然,$todo可以是if/else。重要的一点是,CHILD_FIRST用于在其父(文件夹)之前首先迭代子文件(文件)。

+0

只有SKIP_DOTS被引入在PHP 5.3中?你在哪里看到的? – 2011-05-31 17:48:11

+5

@Alix Axel,[r263239](http://svn.php.net/viewvc/?view=revision&revision=263239) – salathe 2011-05-31 17:56:11

+0

谢谢。另外:你不应该使用'getPathname()'方法而不是'getRealPath()'? – 2011-06-01 08:19:14

0

是这样的吗?

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

我无法解释为什么,但这并不适合我。它一直试图删除一个非空的文件夹。上面的第二个答案很好。 – 2014-01-10 15:19:47

+1

@ buggy3你指的是哪个特定的代码?链接只是链接到这个问题页面。 – cgogolin 2017-04-25 13:58:04

-1

“简单”的代码工作,并且可以通过一个十岁阅读:

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

请注意,我所做的就是扩展/简化和修复(非空的没有工作dir)解决方案: In PHP how do I recursively remove all folders that aren't empty?

12

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

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

'rm -rf /'=='recurseRmdir('/')':) – Arin 2017-01-09 20:56:41

+1

请注意,这不是符号链接安全!您需要在is_dir之后进行健全性检查,以检查它是否为!is_link,否则您可以将符号链接到外部文件夹,然后将其删除,这可能会被视为安全漏洞。所以你应该把'is_dir(“$ dir/$ file”)'改成'is_dir(“$ dir/$ file”)&&!is_link(“$ dir/$ file”)' – Kirab 2017-07-04 08:57:01

-1

我中庸之道使这个代码,从一些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')); 
-1
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); 

} 
-1

例与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); 
    } 
}; 
+0

我用'system 'rm -fr文件夹')' – 2015-03-25 22:49:33

5
<?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; 
} 
+0

相当复杂的建议;-) – Philipp 2015-05-21 19:07:31

+0

@ Philipp是的我猜。那么我做了一个分支https://gist.github.com/mindplay-dk/a4aad91f5a4f1283a5e2,因为我没有得到它的工作,所以我只是想我也可以分享它。 – XzaR 2015-05-24 09:13:00

+2

最优雅,干净,容易阅读;) – 2015-06-23 13:57:08

-1

改性的@XzaR溶液变体。它会删除空文件夹,当所有文件都从中删除时,它会抛出异常而不是返回错误。

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'"); 
     } 
    } 
} 
0

增强@Artefacto的溶液 - 校正输入错误和简化的代码,对于两个工作 - 空& &非空目录。

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

unlinkr功能递归确保它不会删除脚本本身删除指定路径的所有文件夹和文件。

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目录中的所有文件。

-2

我使用此代码...

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

这是递归吗? – Carpetsmoker 2016-03-25 11:30:11

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

如果您回答的问题已经有很多答案,包括已被接受的答案,您需要发布解答,您的答案增加了什么价值,而不仅仅是代码。一般来说,仅有代码的答案是不受欢迎的,但尤其是这种情况。 – 2016-07-14 15:30:12

+0

我投了这个答案并接受了答案。从我的基准检查(没有'unlink','rmdir')来看,'opendir' +'readdir'工作得更快,scandir和RecursiveDirectoryIterator的使用也比所有内存少。要删除文件夹,我必须先“封闭”,我被困在此处。感谢这个答案。 – vee 2017-05-30 13:43:30

0

一旦您完成运行测试,只是删除##unlink#rmdir在课堂上。

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

?> 
0
<?php 

/** 
* code by Nk ([email protected]) 
*/ 

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('@/[email protected]', $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); 
    } 
} 

?> 

cleanup.php:?删除与文件目录吧]

<?php 

/* include.. */ 

filesystem::rrmdir('/var/log'); 
filesystem::rrmdir('./cache'); 

?>