Cron执行PHP脚本时MySQL更新失效及环境变量问询
从现有日志能获取的环境变量相关信息及排查建议
咱们先从你提供的syslog和cronlog输出里,提炼出和环境变量、执行环境相关的关键信息,再给你针对性的排查方向:
1. 执行用户的环境上下文差异
- Cron执行你的
cron_1sec.php时,用的是www-data用户,但要注意:Cron给用户提供的默认环境变量和web服务器(比如Apache/Nginx)运行时的环境完全不是一回事。Web服务器的环境是继承自服务进程的,包含很多预设变量;而Cron的环境非常精简,web环境里有的$_SERVER变量、自定义环境变量,在Cron执行时大概率都不存在。 - 你手动在浏览器执行时,脚本是通过web服务器的www-data上下文运行的,这时候的环境和Cron的www-data环境有本质区别——比如web环境会加载对应模式的php.ini,而Cron调用PHP时用的是CLI模式的配置文件。
2. PHP运行模式的配置差异
- Cronlog里的
PHP Warning: Module 'xdebug' already loaded提示,直接说明Cron执行PHP时用的是CLI模式,而web环境用的是FPM/mod_php模式。两种模式加载的php.ini文件通常是分开的:CLI模式的配置一般在/etc/php/[版本号]/cli/php.ini,web模式的在/etc/php/[版本号]/fpm/php.ini。这会导致很多配置差异,比如include_path、扩展加载规则、内存限制等,都可能间接影响数据库更新操作的行为。
3. Cron环境的核心变量缺失
- syslog里的
No MTA installed, discarding output说明:Cron默认会把脚本的输出通过邮件发送,但因为系统没装邮件传输代理(MTA),所以输出直接丢了。这也侧面反映出Cron的环境里要么没配置MAILTO变量,要么配置了但MTA不可用——而web环境根本不会依赖这个机制。 - 另外,Cron执行时的
PATH变量通常非常短(一般是/usr/bin:/bin),而web服务器的PATH可能包含更多自定义路径。虽然你这里是PHP脚本,但如果脚本里调用了外部命令(比如备份、文件操作工具),PATH差异会出问题;更关键的是,PHP CLI模式可能因为PATH问题找不到某些依赖的扩展或配置文件。
4. 脚本执行的工作目录差异
- Cron执行脚本时的默认工作目录是执行用户的home目录(比如www-data的home可能是
/var/www或者/home/www-data),而web环境执行脚本时,工作目录是脚本所在的目录(也就是/var/www/StartStop/html/includes/)。如果你的脚本里用了相对路径加载文件(比如include('file2.php')而不是绝对路径),Cron执行时会找不到文件,但你说其他操作正常,这个可能性不大,但还是要留意。
针对UPDATE失效的额外排查建议
既然你说只有UPDATE操作失效,其他MySQL操作(查询、数组处理)都正常,那可以试试这些方法定位问题:
- 修改Cron任务,把脚本输出重定向到一个专门的调试日志文件,比如:
然后在脚本里的UPDATE语句后面,加上数据库错误信息输出:/var/www/StartStop/html/includes/cron_1sec.php >> /var/log/cron_debug.log 2>&1
这样就能看到UPDATE操作失败的具体原因了。$result = $db->sql_query("UPDATE `program_schedule` SET `{$key}_delta`= '{$val}' WHERE `chid`={$k}"); var_dump($db->sql_error()); // 输出错误信息 - 对比CLI和web模式的PHP配置:用
sudo -u www-data php -i查看CLI模式的PHP信息,和web环境的phpinfo()输出对比,重点看数据库相关的配置(比如mysqlnd版本、连接超时、字符集等)。 - 确认Cron执行时的数据库连接是否正常:web环境可能用了持久化数据库连接,而CLI模式每次都是新建连接,可能存在权限或者连接参数的差异。
内容的提问来源于stack exchange,提问作者Mantas Kildišis




