2010-07-26 42 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'); 

?> 
相關問題