You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP删除空目录报错:Warning: rmdir(): Directory not empty问题排查

解决rmdir(): Directory not empty警告(空目录删除失败)

这个问题我之前也踩过坑!核心原因是你的glob匹配规则没覆盖到隐藏文件,导致你以为是空的目录里其实还有残留文件,最终触发了rmdir的警告。

问题根源

你代码里用的glob($target . '*', GLOB_MARK)只会匹配不以点(.)开头的普通文件/目录,但Linux/Unix系统里的隐藏文件(比如.htaccess、.gitignore)或者某些遗留的隐藏文件会被漏掉。这些文件留在目录里,就会让rmdir认为目录不为空,从而报错。

另外,glob默认也不会匹配.(当前目录)和..(上级目录),不过这两个不会影响删除,但我们处理的时候需要过滤掉,避免递归出错。

修复后的代码

public function delete_files($target) {
    // 标准化路径,确保末尾有目录分隔符,避免匹配错误
    $target = rtrim($target, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;

    if (is_dir($target)) {
        // 使用GLOB_BRACE匹配普通文件和隐藏文件
        $files = glob($target . '{,.}*', GLOB_BRACE | GLOB_MARK);
        
        foreach ($files as $file) {
            // 跳过当前目录(.)和上级目录(..)
            if ($file === $target . '.' || $file === $target . '..') {
                continue;
            }
            $this->delete_files($file);
        }
        
        // 尝试删除目录前,额外校验是否真的为空
        if (count(glob($target . '{,.}*', GLOB_BRACE)) === 2) { // 只剩.和..两个项
            rmdir($target);
        } else {
            $this->logger->error("Directory $target is not empty after cleanup");
        }
    } elseif (is_file($target)) {
        unlink($target);
    } else {
        $this->logger->error("Could not delete the folder or file: $target");
    }
}

关键修改点

  • 标准化路径:用rtrim和DIRECTORY_SEPARATOR确保路径末尾有分隔符,避免$target . '*'变成/path/to/dir*(可能误匹配到其他同名前缀的目录)。
  • 匹配隐藏文件:{,.}*搭配GLOB_BRACE,同时覆盖普通文件(*)和隐藏文件(.*)的匹配。
  • 过滤特殊目录:跳过.和..,防止递归处理上级目录或者陷入无限循环。
  • 额外校验:删除前再检查目录状态,避免因意外残留文件导致的报错,也方便排查问题。

这样修改后,不管目录里有没有隐藏文件,都能被彻底清理,空目录也能正常删除啦!

内容的提问来源于stack exchange,提问作者Tuz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:41:56