PHP定时清理日志需用cron调用脚本,核心是glob遍历+filemtime判断+unlink删除;推荐用find命令替代,如find /var/log/myapp/ -name "*.log" -mtime +7 -delete,并注意权限、绝对路径及测试验证。

PHP 脚本里用 unlink() 清理旧日志文件最直接
PHP 本身没有内置定时任务能力,所谓“PHP 定时清理 logs”,本质是写一个 PHP 脚本负责删除过期日志,再靠系统级定时器(如 cron)定期调用它。脚本核心就是遍历日志目录、判断修改时间、用 unlink() 删除符合条件的文件。
常见错误是直接 filemtime() 拿到时间后硬写比较逻辑,却忽略时区或时间戳精度问题;更稳妥的做法是用 time() - $max_age 做基准,再跟 filemtime($file) 对比:
foreach (glob('/var/log/myapp/*.log') as $file) {
if (is_file($file) && filemtime($file) < time() - 86400 * 7) { // 7天前
unlink($file);
}
}- 务必加
is_file($file)判断,避免符号链接或目录被误删 -
glob()返回空数组时循环不执行,无需额外判空 - 不要用
date('Y-m-d', ...)字符串比较,易出错且慢
cron 是唯一靠谱的“自动”触发方式
Windows 的计划任务、Linux 的 cron 才是真正执行定时动作的载体。PHP 脚本只是被调用的工具。写好脚本(比如叫 clean_logs.php)后,在终端运行 crontab -e 加一行:
0 2 * * * /usr/bin/php /path/to/clean_logs.php > /dev/null 2>&1
这表示每天凌晨 2 点执行。关键点:
立即学习“PHP免费学习笔记(深入)”;
- 必须写绝对路径调用
php(which php查),不能只写php - 脚本路径也要绝对,相对路径在 cron 环境下大概率失效
-
> /dev/null 2>&1是为了屏蔽输出,否则 cron 可能发邮件报警 - 测试时可先改成
* * * * *(每分钟一次),确认能删再改回正式周期
用 find 命令替代 PHP 脚本更轻量高效
如果日志都在标准目录(如 /var/log/),直接用系统命令反而更稳——不依赖 PHP 运行环境,也不怕脚本异常退出:
find /var/log/myapp/ -name "*.log" -mtime +7 -delete
这条命令含义清晰:找 /var/log/myapp/ 下所有 .log 文件,修改时间超过 7 天的直接删。注意:
-
-mtime +7表示“7*24 小时之前”,不是“7 天整”,和 PHP 的time() - 604800语义一致 - 首次测试务必把
-delete换成-ls,先看会删哪些文件 - 某些老系统不支持
-delete,可改用-exec rm {} \; - 该命令可直接写进 cron,无需封装成 PHP 脚本
权限和路径错误是 90% 的失败原因
脚本跑不通,八成是权限或路径问题。cron 默认以当前用户身份运行,但日志文件可能属 www-data 或 root,PHP 进程没权限删;或者脚本里写的日志路径是开发机路径,上线后根本不存在。
排查步骤很实际:
- 手动执行一遍:
php /path/to/clean_logs.php,看报什么错 - 检查日志文件属主:
ls -l /var/log/myapp/,确认 PHP 进程用户有w权限 - 在脚本开头加
error_log("Running as: " . get_current_user(), 3, "/tmp/clean.log");查实际运行用户 - 所有路径用绝对路径,别信
__DIR__或getcwd()—— cron 下工作目录不可控
真正麻烦的从来不是怎么删,而是删之前确认删得对、删得稳、删得没人告你。











