$_GET在CLI下始终为空,因其仅由Web服务器在HTTP请求解析时自动填充,而CLI无URL上下文,$argv才承载命令行参数;需用parse_str+urldecode或getopt手动解析。
PHP 命令行(CLI)本身不解析
,因为
是 Web SAPI(如 Apache、FPM)在处理 HTTP 请求时自动填充的超全局变量;CLI SAPI 根本不读取 URL 查询字符串,直接访问
永远是空数组。
为什么
在 CLI 下始终为空
CLI 模式没有 HTTP 请求上下文,
、
、
等均不会被自动填充。即使你运行
,这个
会被当作独立命令行参数传入
,而非注入
。
是脚本路径,
开始才是用户传入的参数(如
)
仅由 Web 服务器在请求解析阶段写入,CLI 不触发该逻辑
试图在 CLI 中依赖
会导致逻辑断裂或静默失败
如何手动模拟
参数解析
最可靠的方式是遍历
,按
格式解析并写入
(或更推荐:用独立变量接收)。注意不要直接覆盖
,除非你明确知道后续代码会读它且无副作用。
用
可批量解析形如
的参数
但需警惕空格、特殊字符未编码问题——CLI 不做 URL 解码,
不会自动转为空格,得先
更健壮的做法是逐个处理:
如果参数含空格(如
),shell 会将其拆成两个参数,必须用引号包裹:
用
更规范地处理命令行参数
比起手动解析
字符串,
是 PHP 内置的 POSIX 兼容参数解析函数,支持短选项(
)、长选项(
)、必需/可选参数,也更符合 CLI 工具惯例。
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
立即学习
“
PHP免费学习笔记(深入)
”;
定义规则:
表示
和
都接受值
调用方式:
或
结果存于关联数组:
或
,无需手动
不兼容带等号的短选项(
在部分系统不被识别),建议统一用长选项或空格分隔
Web 脚本复用 CLI 时的兼容性要点
如果你的 PHP 文件既要跑在 Web 上又要跑在 CLI 上,并希望统一使用
,必须显式桥接:
加判断:
避免污染全局:
在 CLI 下本不存在,直接赋值虽可行,但可能掩盖类型不一致问题;建议封装为
函数,内部根据 SAPI 分支读取
测试时注意:Web 环境下
来自 query string,CLI 下来自
,二者编码行为不同(Web 自动解码,CLI 不解码),容易在中文或特殊字符上出错
真正麻烦的不是怎么“模拟”,而是忘记 CLI 和 Web 的执行环境本质不同——参数来源、编码处理、生命周期全都不一样。硬塞
往往只是掩盖了架构混用的问题。
$_GET$_GET$_GET$_GET$_GET$_POST$_COOKIEphp script.php?id=123id=123$argv$_GET$argv[0]$argv[1]"id=123"$_GET$_GET$_GET$argvkey=value$_GET$_GETparse_str(implode('&', array_slice($argv, 1)), $_GET)php test.php a=1 b=2 c=hello%20world%20urldecode()foreach (array_slice($argv, 1) as $arg) { if (strpos($arg, '=') !== false) { list($k, $v) = explode('=', $arg, 2); $_GET[$k] = urldecode($v); } }name=John Doephp test.php "name=John Doe"getopt()key=valuegetopt()-a--id=123$options = getopt('i:', ['id:']);-i--idphp script.php -i 123php script.php --id=123$options['i']$options['id']urldecode-i=123$_GETif (PHP_SAPI === 'cli') { parse_cli_get_args(); }$_GETget_input('id')$_GET$argv$_GET