0

0

如何扩展 PHP 文件扫描函数以支持多目录数组输入

碧海醫心

碧海醫心

发布时间:2026-02-11 18:46:43

|

636人浏览过

|

来源于php中文网

原创

如何扩展 PHP 文件扫描函数以支持多目录数组输入

本文介绍如何改造原有的单目录递归扫描函数,使其支持传入目录路径数组,一次性扫描多个根目录下的所有文件与子目录,并保持原有过滤、递归及类型控制逻辑。

在实际开发中,我们常需批量扫描多个不相关的目录(例如:/var/log/app1、/var/log/app2、/tmp/cache),而原 scanFiles() 函数仅接受单一字符串路径,无法直接满足该需求。最简洁且兼容性强的解决方案是:将参数 $directory 改为可接受字符串或数组类型,并在函数入口做类型判断与统一处理——而非强制要求调用方始终传数组(兼顾向后兼容性)。

以下是优化后的完整实现,支持单路径(string)和多路径(array)两种调用方式:

public static function scanFiles($directories, $recursive = true, $listDirs = false, $listFiles = true, $exclude = '') {
    $arrayItems = [];

    // 兼容单路径字符串:自动转为单元素数组
    $dirs = is_string($directories) ? [$directories] : $directories;

    foreach ($dirs as $directory) {
        // 跳过空路径或非目录
        if (!is_dir($directory) || !is_readable($directory)) {
            continue;
        }

        $handle = opendir($directory);
        if (!$handle) {
            continue;
        }

        while (false !== ($file = readdir($handle))) {
            // 默认排除项:. / .. / .git / .svn / .md / Thumbs.db / .DS_Store / .html
            $skip = preg_match("/(^(([\.]){1,2})$|(\.(svn|git|md))|(Thumbs\.db|\.DS_STORE|\.html))$/iu", $file);

            // 自定义正则排除(如需)
            $skipByExclude = false;
            if ($exclude && !empty($exclude)) {
                $skipByExclude = (bool) preg_match($exclude, $file);
            }

            if (!$skip && !$skipByExclude) {
                $fullPath = $directory . DS . $file;

                if (is_dir($fullPath)) {
                    if ($recursive) {
                        // 递归扫描子目录(注意:此处仍传单路径字符串,递归调用会再次自动适配)
                        $arrayItems = array_merge($arrayItems, self::scanFiles($fullPath, $recursive, $listDirs, $listFiles, $exclude));
                    }
                    if ($listDirs) {
                        $arrayItems[] = $fullPath;
                    }
                } else {
                    if ($listFiles) {
                        $arrayItems[] = $fullPath;
                    }
                }
            }
        }
        closedir($handle);
    }

    return $arrayItems;
}

使用示例

// 扫描单个目录(完全兼容旧用法)
$files = MyScanner::scanFiles('/var/www/html');

// 扫描多个目录
$paths = ['/var/log/nginx', '/var/log/php-fpm', '/tmp/uploads'];
$allFiles = MyScanner::scanFiles($paths, true, false, true, '/^test_.*\.log$/i');

// 同时列出目录和文件(含递归)
$mixed = MyScanner::scanFiles(['/src', '/tests'], true, true, true);

⚠️ 注意事项与最佳实践

ChatGPT Website Builder
ChatGPT Website Builder

ChatGPT网站生成器,AI对话快速生成网站

下载

立即学习PHP免费学习笔记(深入)”;

  • 路径安全性:调用前建议对 $directories 中每个路径执行 realpath() 和白名单校验,防止路径遍历攻击(尤其在用户可控输入场景);
  • 性能提示:大量目录或深层嵌套时,opendir() + readdir() 效率优于 glob(),但需注意 open_basedir 限制;
  • 重复路径处理:函数本身不自动去重,若传入重复路径或存在符号链接交叉,需在调用层自行 array_unique($result, SORT_STRING);
  • DS 常量:确保已定义 DS(如 define('DS', DIRECTORY_SEPARATOR);),以保证跨平台兼容性;
  • 错误抑制:当前代码跳过不可读目录,如需调试,可添加 error_log("Cannot read directory: $directory");。

该方案在零破坏原有接口的前提下,显著提升函数实用性,适用于日志聚合、资源打包、静态分析等典型多源扫描场景。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

688

2023.08.02

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1547

2023.10.24

typedef和define区别
typedef和define区别

typedef和define区别在类型检查、作用范围、可读性、错误处理和内存占用等。本专题为大家提供typedef和define相关的文章、下载、课程内容,供大家免费下载体验。

113

2023.09.26

define的用法
define的用法

define用法:1、定义常量;2、定义函数宏:3、定义条件编译;4、定义多行宏。更多关于define的用法的内容,大家可以阅读本专题下的文章。

347

2023.10.11

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

488

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

214

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1547

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

637

2023.11.24

2026春节习俗大全
2026春节习俗大全

本专题整合了2026春节习俗大全,阅读专题下面的文章了解更多详细内容。

68

2026.02.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 11.5万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11.2万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号