PHP递归遍历目录及子目录搜索指定文件的函数报错求解
代码存在的核心问题
- 未过滤
.、..两个系统目录下默认存在的特殊路径项,遍历到这两个项时会触发无效递归,导致路径错误甚至死循环 - 匹配到目标文件时返回路径拼接错误:
$entry本身就是目标文件名,代码额外拼接了一层/$filename,最终返回的路径不存在 - 递归逻辑错误:遍历到第一个子目录时就直接
return递归结果,如果该子目录下没有目标文件,会直接终止整个遍历流程,不会继续扫描同级其他目录、文件,比如示例结构中先遍历到directory_1时,就不会再扫描后面的directory_2 - 未做目录打开失败的异常判断,也未在遍历结束后关闭目录句柄,容易触发资源泄漏
- 文件名匹配大小写敏感,如果目标文件实际存储为
myfile(全小写),和定义的myFile(驼峰)无法匹配
修复后可直接运行的代码
$rootDir = realpath($_SERVER["DOCUMENT_ROOT"]) . '/file'; $filename = 'myFile'; public function searchFile($rootDir, $filename) { if (!is_dir($rootDir)) { return false; } $dir = opendir($rootDir); while ($entry = readdir($dir)) { // 跳过特殊目录项 if ($entry === '.' || $entry === '..') { continue; } $fullPath = $rootDir . DIRECTORY_SEPARATOR . $entry; // 命中目标文件直接返回正确路径 if (is_file($fullPath) && $entry === $filename) { closedir($dir); return $fullPath; } // 递归遍历子目录,子目录找到结果才返回,否则继续扫当前层 if (is_dir($fullPath)) { $searchResult = $this->searchFile($fullPath, $filename); if ($searchResult !== false) { closedir($dir); return $searchResult; } } } closedir($dir); // 当前目录及所有子目录无目标文件时返回false return false; }
更稳定的实现方案
直接使用PHP内置的递归目录迭代器实现,不需要手动处理目录句柄、特殊路径等边界问题,代码更简洁容错性更高:
public function searchFile($rootDir, $filename) { if (!is_dir($rootDir)) { return false; } $dirIterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($rootDir, RecursiveDirectoryIterator::SKIP_DOTS) ); foreach ($dirIterator as $file) { if ($file->isFile() && $file->getFilename() === $filename) { return $file->getRealPath(); } } return false; }
如果需要大小写不敏感匹配,把文件名判断逻辑替换为
strcasecmp($file->getFilename(), $filename) === 0即可。
内容的提问来源于stack exchange,提问作者anthony pivost
相关产品推荐
相关产品推荐

