PHP文件自动归类需手动编写脚本,用scandir+pathinfo提取特征,preg_match匹配关键词(如“发票”),mkdir+rename安全移动;跨分区用copy+unlink;glob更简洁筛选扩展名;定时执行需加锁防重复。

PHP 本身没有内置的“自动归类”能力,必须靠你定义规则 + 手动扫描 + 搬移文件 —— 这不是开箱即用的功能,而是需要自己写逻辑的整理脚本。
如何用 scandir + pathinfo 提取文件特征
归类的前提是识别文件类型。不能只看后缀,还要考虑内容或命名习惯(比如“2024-05-xx_发票.pdf”应进“发票”目录)。scandir 列出所有项,pathinfo 拆出扩展名、文件名,再配合 preg_match 做关键词匹配:
-
pathinfo($file, PATHINFO_EXTENSION)获取小写扩展名(注意大小写敏感问题) - 对文件名做模糊判断:
preg_match('/发票|invoice/i', $filename) - 跳过
.和..,也建议跳过已存在的分类目录名,避免循环处理
怎么安全地移动文件到目标文件夹(mkdir + rename)
直接 rename 是最轻量的搬移方式(同一分区下是原子操作),但必须确保目标目录存在且可写:
- 用
is_dir($dest_dir) || mkdir($dest_dir, 0755, true)创建多级目录(第三个参数true关键) -
rename($src, $dest)成功返回true,失败不报错,务必检查返回值 - 若跨文件系统(如从 /tmp 移到 /home),
rename会失败,此时得用copy+unlink,并注意大文件的内存和超时问题
为什么用 glob 比 scandir 更适合按类型筛选
如果你只按扩展名归类(比如所有 .jpg 进 images/),glob 更简洁、更少出错:
立即学习“PHP免费学习笔记(深入)”;
-
glob($source . '/*.pdf')直接拿到全部 PDF 路径数组,不用再过滤 - 支持通配符组合:
glob($source . '/{*.jpg,*.png}', GLOB_BRACE)(注意开启GLOB_BRACE) - 比
scandir+foreach+pathinfo+if少三层嵌套,逻辑更平直 - 但注意:
glob不递归,深层子目录需配合RecursiveIteratorIterator或自己写递归
定时执行和防重复的关键点(file_put_contents 记录时间戳)
没人会手动点运行,得靠 cron 定时调用。但要防止上一次没跑完、下一次又启动(尤其大目录):
- 脚本开头用
file_exists($lock_file) && time() - filemtime($lock_file) 判断是否还在运行中 - 成功跑完再更新锁文件:
file_put_contents($lock_file, date('c')) - 别用数据库存状态——单机脚本,文件锁最轻量;用
flock太重,且 PHP CLI 下容易漏释放 - 日志写入用
error_log("moved $file to $dest", 3, $log_path),别用echo,cron 不捕获 stdout
真正难的不是搬文件,而是规则设计:哪些文件该归一类?命名混乱时怎么 fallback?要不要保留原路径结构?这些没法靠函数解决,得根据你的实际文件命名习惯一条条补规则。











