2010-12-20 205 views
4

我有這段代碼遞歸刪除文件和目錄。它工作正常,但有一點問題。如果$ path =/var/www/foo /它會刪除foo內的所有內容,但不包含foo。我也想刪除foo目錄。任何想法?遞歸刪除

public function delete($path) { 
    if(!file_exists($path)) { 
     throw new RecursiveDirectoryException('Directory doesn\'t exist.'); 
    } 

    $directoryIterator = new DirectoryIterator($path); 

    foreach($directoryIterator as $fileInfo) { 
     $filePath = $fileInfo->getPathname(); 

     if(!$fileInfo->isDot()) { 
      if($fileInfo->isFile()) { 
       unlink($filePath); 
      } 
      else if($fileInfo->isDir()) { 
       if($this->emptyDirectory($filePath)) { 
        rmdir($filePath); 
       } 
       else { 
        $this->delete($filePath); 
        rmdir($filePath); 
       } 
      } 
     } 
    } 
} 
+0

@stereofrog:幾乎所有的東西? – Bobby 2010-12-21 08:02:00

回答

3

你錯過了最後一個rmdir$this->delete($path)這樣以後你可以或者把它:

$this->delete($path); 
rmdir($path); 

或者你可以改變foreach -loop這樣的:

public function delete($path) { 
    //snip 

    foreach($directoryIterator as $fileInfo) { 
     //snip 
       else { 
        $this->delete($filePath); 
       } 
      } 
     } 
    } 

    rmdir($path); 
} 

而且,我當然希望你確認你所得到的路徑存在,如果這可見用戶(如「刪除一切都在我的網絡空間」 - 函數。我的意思是,你如果有人通過/etc/到那裏有很多的樂趣。

+1

是的,然後你可以在'$ this-> delete($ filePath);'後面刪除它。 – 2010-12-20 14:50:50

+0

不......我不知道爲什麼,但$ path(目錄)不再存在。謝謝。 – thom 2010-12-20 14:52:19

+0

@Spinner Norman:我更加想到在foreach循環之後添加它。 – Bobby 2010-12-20 14:52:34

-1
function delete($path){ 
    if(!file_exists($path)) { 
     throw new RecursiveDirectoryException('Directory doesn\'t exist.'); 
    } 

    $directoryIterator = new DirectoryIterator($path); 

    foreach($directoryIterator as $fileInfo) { 
     $filePath = $fileInfo->getPathname(); 

     if(!$fileInfo->isDot()) { 
      if($fileInfo->isFile()) { 
       unlink($filePath); 
      } 
      else if($fileInfo->isDir()) { 
       if($this->emptyDirectory($filePath)) { 
        rmdir($filePath); 
       } 
       else { 
        $this->delete($filePath); 
        rmdir($filePath); 
       } 
      } 
     } 
    } 
    rmdir($path); 
} 

12

爲什麼即使在你的功能遞歸?

public function delete($path) { 
    $it = new RecursiveIteratorIterator(
     new RecursiveDirectoryIterator($path), 
     RecursiveIteratorIterator::CHILD_FIRST 
    ); 
    foreach ($it as $file) { 
     if (in_array($file->getBasename(), array('.', '..'))) { 
      continue; 
     } elseif ($file->isDir()) { 
      rmdir($file->getPathname()); 
     } elseif ($file->isFile() || $file->isLink()) { 
      unlink($file->getPathname()); 
     } 
    } 
    rmdir($path); 
} 

它有效,因爲RII::CHILD_FIRST在父元素之前遍歷子元素。所以當它到達目錄時,它應該是空的。

但實際的錯誤是由於您刪除目錄的位置。在內部目錄中,您可以在父迭代中執行此操作。這意味着你的根目錄永遠不會被刪除。我建議在本地刪除迭代中執行此操作:

public function delete($path) { 
    if(!file_exists($path)) { 
     throw new RecursiveDirectoryException('Directory doesn\'t exist.'); 
    } 

    $directoryIterator = new DirectoryIterator($path); 

    foreach($directoryIterator as $fileInfo) { 
     $filePath = $fileInfo->getPathname(); 
     if(!$fileInfo->isDot()) { 
      if($fileInfo->isFile()) { 
       unlink($filePath); 
      } elseif($fileInfo->isDir()) { 
       if($this->emptyDirectory($filePath)) { 
        rmdir($filePath); 
       } else { 
        $this->delete($filePath); 
       } 
      } 
     } 
    } 
    rmdir($path); 
} 

請注意兩個更改。我們只刪除迭代中的空目錄。調用$this->delete()就可以處理您的刪除操作。第二個變化是增加在方法結束的最後rmdir的...

+0

謝謝,我會盡力... – thom 2010-12-20 15:28:00

+0

它的工作。謝謝。 – thom 2010-12-20 16:04:32

+1

這適用於Linux,但在Windows中,當刪除* parent *文件夾時,我有一些「權限被拒絕」的錯誤,它是空的(因爲它應該是因爲遞歸刪除其內容)。我必須使用函數的'rmdir($ path)'* out *。 '$ path = realpath(「./ test」);刪除($ PATH);命令rmdir($ PATH);' – nevvermind 2011-08-04 09:08:22

0

試試這個

未設置($ directoryIterator); rmdir($ filePath);