PHP定时执行需依赖系统调度工具(Linux用cron,Windows用任务计划程序),不可用sleep()模拟;批量文件处理须用标记文件+原子操作防重复/遗漏;注意路径权限、用户差异及失败通知机制。

PHP脚本怎么触发定时执行
PHP本身没有内置定时器,所谓“定时”必须依赖操作系统级的调度工具。在Linux上用cron,Windows上用任务计划程序——PHP脚本只是被调用的一段逻辑,不是主动计时的主体。
常见错误是试图在PHP里用sleep()或循环+时间判断来“模拟定时”,这会导致进程常驻、资源占用高、重启后失效,且无法保证精度。
- Linux下编辑定时任务:运行
crontab -e,添加类似0 */2 * * * /usr/bin/php /var/www/scripts/batch_cleanup.php(每两小时执行一次) - 确保PHP CLI路径正确:用
which php确认,不要直接写php,避免环境变量差异 - 脚本开头加
#!/usr/bin/env php并设可执行权限(chmod +x batch_cleanup.php),可简化crontab写法
批量处理文件时怎么避免重复或漏处理
关键在于状态记录和原子操作。不推荐“遍历目录→处理→删源文件”这种裸操作,容易因中断导致文件丢失或重复处理。
更稳妥的做法是用一个标记文件或数据库记录已处理的文件名/哈希/时间戳,每次只处理“未标记”的新文件。
立即学习“PHP免费学习笔记(深入)”;
- 用
glob()或scandir()获取待处理文件列表,但先过滤掉已处理过的(例如检查同名.done标记文件是否存在) - 处理完单个文件后,立即生成对应标记:
file_put_contents($file . '.done', time()),比改名或移动更轻量且可逆 - 若需强一致性,把“读取→处理→写标记”放在
flock()临界区内,防止同一脚本被cron并发多次触发时冲突
PHP批量文件操作常见的路径与权限坑
Web服务器用户(如www-data)和crontab默认用户(如root或你的登录用户)往往不同,导致脚本在浏览器能跑、在定时里报错“Permission denied”或“No such file or directory”。
- 所有路径必须用绝对路径:
/var/www/uploads/,不能用./uploads/或__DIR__(因为crontab工作目录不固定) - 检查目标目录的属主和权限:
ls -ld /var/www/uploads/,确保crontab执行用户有读写权限 - 如果涉及
move_uploaded_file()或copy()失败,大概率是SELinux或AppArmor拦截(Linux发行版如CentOS/RHEL默认启用),临时验证可用setenforce 0,长期应配策略而非关禁用
怎么让批量任务失败时有人知道
静默失败是定时任务最危险的状态。cron默认只在有输出(stdout/stderr)时发邮件,但多数PHP脚本没输出,出错了也石沉大海。
- 在crontab里重定向并加通知:
0 */2 * * * /usr/bin/php /path/to/script.php >> /var/log/batch.log 2>&1 || echo "batch failed at $(date)" | mail -s "PHP batch alert" admin@example.com - 脚本内用
error_log()记录关键步骤,配合try/catch捕获异常,避免未捕获致命错误直接中断 - 对重要操作(如删除原始文件),加
if (unlink($file)) { /* success */ } else { error_log("unlink failed: $file"); },别假设一定成功
真正难的不是写几行foreach,而是让脚本在无人看管时持续可靠运行——路径、权限、并发、失败反馈,每个点都可能在某次系统更新后突然崩掉。



















