2010-12-20 155 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);