递归删除 [英] Recursive delete

查看:143
本文介绍了递归删除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这段代码可以递归删除文件和目录.它工作正常,但有一点问题.如果$ path =/var/www/foo/,它将删除foo内部的所有内容,但不会删除foo.我也想删除foo目录.任何的想法?

I have this code to recursive delete files and directories. It works fine but has a little problem. If $path = /var/www/foo/ it will delete everything inside of foo, but not foo. I want to delete foo directory too. Any idea?

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

推荐答案

为什么还要在函数中递归?

Why even recurse in your function?

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遍历父元素之前的子元素.因此,当它到达目录时,它应该为空.

It works, because RII::CHILD_FIRST iterates over the children before the parent element. So by the time it reaches the directory, it should be empty.

但是实际错误是由于删除目录所致.在内部目录中,您可以在父级迭代中执行此操作.这意味着您的根目录将永远不会被删除.我建议在本地删除迭代中执行此操作:

But the actual error is due to where you delete your directories. In inner directories you do it in the parent iteration. That means that your root directory will never be deleted. I'd suggest doing it in the local delete iteration:

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 ...

Note the two changes. We're only deleting the empty directories inside of the iteration. Calling $this->delete() on it will handle the deletion for you. The second change is the addition of the final rmdir at the end of the method...

这篇关于递归删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆