
本文介绍使用 PHP 的 glob() 和 filemtime() 函数,根据文件名前缀(如 "a" 或 "b")及最后修改时间(分别对应 1 天或 7 天阈值)精准筛选并删除过期文件的完整实现方案。
本文介绍使用 php 的 `glob()` 和 `filemtime()` 函数,根据文件名前缀(如 "a" 或 "b")及最后修改时间(分别对应 1 天或 7 天阈值)精准筛选并删除过期文件的完整实现方案。
在实际项目中(如上传临时文件清理、日志归档、缓存管理),常需按命名规则与时间维度组合清理文件。例如:所有以 a 开头的文件若超过 24 小时即删除;以 b 开头的文件则放宽至 7 天。直接调用 shell 命令(如 find)虽可行,但存在跨平台兼容性差、权限风险高、难以调试等问题。推荐采用纯 PHP 方案,兼顾可移植性、安全性与可维护性。
以下为优化后的完整实现:
<?php $dir = "./uploads/";
// 使用 glob 一次性匹配所有以 'a' 或 'b' 开头的文件(注意:glob 不支持正则,[ab]* 表示首字符为 a 或 b)
$files = glob($dir . '[ab]*');
if ($files !== false) {
foreach ($files as $file) {
// 跳过目录,确保只处理文件
if (!is_file($file)) {
continue;
}
$mtime = filemtime($file);
$now = time();
// 规则1:以 'a' 开头且超过 1 天(86400 秒)
if (basename($file)[0] === 'a' && $mtime < $now - 86400) {
if (@unlink($file)) {
echo "✓ Deleted: " . basename($file) . " (older than 1 day)\n";
} else {
echo "✗ Failed to delete: " . basename($file) . "\n";
}
}
// 规则2:以 'b' 开头且超过 1 周(604800 秒)
elseif (basename($file)[0] === 'b' && $mtime < $now - 604800) {
if (@unlink($file)) {
echo "✓ Deleted: " . basename($file) . " (older than 7 days)\n";
} else {
echo "✗ Failed to delete: " . basename($file) . "\n";
}
}
}
} else {
echo "No matching files found in {$dir}\n";
}
?>
✅ 关键改进说明:
- 使用 basename($file)[0] 精确判断首字母,避免 glob($dir."a*") 在循环内重复执行(原答案中该写法逻辑错误:每次遍历都重新 glob 所有 a* 文件,导致性能浪费且条件误判);
- 显式调用 is_file() 过滤目录项,防止 unlink() 对目录报错;
- 添加操作反馈(成功/失败提示),便于调试与日志追踪;
- 使用 @unlink() 抑制警告,配合手动错误提示,提升健壮性;
- 时间计算基于 time() 与 filemtime() 的秒级差值,语义清晰、无时区歧义。
⚠️ 注意事项:
- 确保 PHP 进程对目标目录具有读取和写入权限;
- 生产环境建议先注释 unlink() 行,改为 echo 预览将被删除的文件,验证逻辑无误后再启用;
- 若需递归处理子目录,请改用 RecursiveIteratorIterator + RegexIterator 或 scandir() 递归实现;
- 对于海量文件,可考虑分批处理或结合 pcntl_fork() 异步执行,避免超时。
该方案简洁、可靠、符合 PSR-12 编码规范,可直接集成至定时任务(如 Linux crontab 或 Windows Task Scheduler 调用 CLI 模式 PHP)中,实现自动化文件生命周期管理。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











