我有这个代码来递归删除文件和目录。它工作正常,但有一点问题。如果$ 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 :(得分: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
...
答案 1 :(得分:3)
你遗失了一个rmdir
。您可以在$this->delete($path)
之后调用它:
$this->delete($path);
rmdir($path);
或者您可以像这样更改foreach
- 循环:
public function delete($path) {
//snip
foreach($directoryIterator as $fileInfo) {
//snip
else {
$this->delete($filePath);
}
}
}
}
rmdir($path);
}
另外,我确定希望你验证你到达那里的路径,如果这对用户可见(比如“删除我的网站空间上的所有内容”功能)。我的意思是,如果有人通过你会有很多乐趣/etc/
进入那里。
答案 2 :(得分:0)
试试这个
unset($ directoryIterator); 命令rmdir($文件路径);
答案 3 :(得分:-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);
}