crontab中php脚本不执行的主因是路径、权限、环境变量和日志缺失;需用绝对路径、显式指定php解释器、检查用户权限、声明环境变量、重定向日志并手动重载。

crontab 里 php 脚本不执行,先看绝对路径有没有写错
Linux 的 crontab 默认工作目录是用户家目录(~),不是你的项目根目录。如果你在脚本里用 require 'config.php' 或 file_get_contents('data/log.txt'),它会去家目录下找,而不是你期望的项目路径。
解决办法只有一条:所有文件引用都用绝对路径。
- 在 crontab 中调用时,显式指定 PHP 解释器和脚本全路径:
/usr/bin/php /var/www/myapp/scripts/clean_cache.php - 脚本内部也统一用
__DIR__或dirname(__FILE__)拼接依赖路径,比如:require __DIR__ . '/../config.php'; - 别信相对路径 +
chdir()临时切换目录——cron 环境不可靠,chdir()可能失败且无提示
php 命令行权限和 web 权限不是一回事
Web 服务器(如 nginx + php-fpm)跑脚本用的是 www-data 或 nginx 用户,而 crontab 默认用当前登录用户(比如 ubuntu)。这两个用户对文件的读写权限很可能不同。
典型表现是:网页能跑通,定时任务报 Permission denied 或 failed to open stream。
立即学习“PHP免费学习笔记(深入)”;
- 检查脚本本身是否可执行:
chmod +x /var/www/myapp/scripts/clean_cache.php(非必须,但建议) - 重点检查脚本要读写的文件/目录归属和权限,比如日志目录:
ls -ld /var/www/myapp/logs/;确保 cron 所用用户有写权限 - 如果必须用特定用户运行,不要在个人 crontab 里写,改用系统级 cron:
sudo crontab -u www-data -e,然后加任务
环境变量缺失导致 php 找不到扩展或命令
crontab 不加载用户的 ~/.bashrc 或 ~/.profile,所以 PATH、PHP_INI_PATH、甚至某些扩展(如 pdo_mysql)可能在 cron 里不可用。
常见症状:脚本直接退出、报 Class not found、command not found: php,但手动执行完全正常。
- 在 crontab 第一行加上环境声明:
SHELL=/bin/bash和PATH=/usr/local/bin:/usr/bin:/bin - 更稳妥的方式是,在命令前显式指定完整路径:
/usr/bin/php -c /etc/php/8.1/cli/php.ini /var/www/myapp/scripts/clean_cache.php - 调试时加日志输出环境信息:
/usr/bin/php -i | grep 'Loaded Configuration File\|extension_dir' >> /tmp/cron_debug.log 2>&1
log 输出被吞掉,根本不知道哪一步挂了
crontab 默认把 stdout/stderr 丢进邮件系统(多数线上服务器没配 mail 服务),或者直接丢弃。不加重定向,等于“静默失败”。
- 每条 cron 任务末尾必须加日志重定向:
> /var/log/myapp/cron_clean.log 2>&1 - 避免日志无限增长,加简单轮转逻辑(不用 logrotate 也可):
0 2 * * * /usr/bin/php /var/www/myapp/scripts/clean_cache.php >> /var/log/myapp/cron_clean.log 2>&1 && tail -n 1000 /var/log/myapp/cron_clean.log > /var/log/myapp/cron_clean.log.tmp && mv /var/log/myapp/cron_clean.log.tmp /var/log/myapp/cron_clean.log - 别依赖
echo或var_dump()—— 加error_log('step 1 done', 3, '/tmp/cron_debug.log');更可靠,因为不受输出缓冲影响
最常被忽略的是:crontab 编辑保存后不会自动 reload,必须退出编辑器并确认没有语法错误(比如最后一行没换行符,某些版本会静默忽略整条任务)。改完务必执行 sudo systemctl status cron 看有没有报错,再查日志。











