为何通过Cron Job传递参数时PHP的$argv始终为空?
咱们先理清楚$argv能正常工作的核心前提:它是PHP CLI(命令行界面)模式下才会自动填充的变量,而且需要php.ini里的register_argc_argv配置项设为On。结合你的PHP 7.1环境和Cron命令,我整理几个最可能的遗漏点:
1. 确认你调用的是PHP CLI版本
很多系统里会同时存在CLI和CGI/FastCGI版本的PHP,Cron里的/usr/local/bin/php可能指向的是CGI版本——而CGI模式下$argv是不会自动生效的。
你可以先在终端执行这个命令确认版本类型:
/usr/local/bin/php -v
如果输出里带有cli字样,那就是正确的CLI版本;如果是cgi-fcgi之类的标识,你需要改成调用CLI版本的PHP,比如路径可能是/usr/local/bin/php-cli,或者直接用php-cli命令替换php。
2. 检查php.ini中的register_argc_argv配置
哪怕是CLI模式,只要php.ini里的register_argc_argv被设为Off,$argv就会是空数组。
你可以执行这个命令查看当前CLI模式下的配置值:
/usr/local/bin/php -i | grep register_argc_argv
如果结果显示register_argc_argv => Off => Off,那你需要修改对应的php.ini文件(注意CLI模式通常有单独的php.ini,和Web环境用的不是同一个),把register_argc_argv = Off改成register_argc_argv = On,下次Cron执行时就会生效。
3. 确认脚本的参数处理逻辑
另外要注意:param=test这种写法在CLI下不会自动解析成$_GET参数,$argv会把它当成一个整体的参数,也就是$argv[1]的值是param=test。如果想解析成键值对,你需要自己处理,比如:
if (isset($argv[1])) { parse_str($argv[1], $params); echo $params['param']; // 输出test }
不过如果你的$argv完全为空,那大概率不是这个问题,前面两个原因的可能性更高。
4. 排查Cron的环境变量差异
Cron的运行环境和你登录终端的环境可能不一样,有时候PATH变量不同,导致调用的PHP不是你预期的版本。你可以临时修改Cron条目来输出环境信息:
* * * * * /usr/local/bin/php -i > /tmp/php-cron-info.txt
执行后查看/tmp/php-cron-info.txt里的内容,确认PHP版本、配置路径等信息是否和终端里的一致。
内容的提问来源于stack exchange,提问作者Tim

