$_server['query_string'] 是获取原始查询字符串最轻量准确的方式,原样返回问号后内容,不解析不解码,适用于web环境;需配合parse_str()解析为数组,注意其覆盖规则与$_get差异。

直接用 $_SERVER['QUERY_STRING'] 拿原始参数串
如果只是要问号后面那一整段(比如 name=jack&age=25&city=%E5%8C%97%E4%BA%AC),不解析、不转义、不处理重复键,$_SERVER['QUERY_STRING'] 是最轻量、最准确的方式。它原样返回 URL 中 ? 后的所有内容,不含 ? 本身。
注意点:
-
$_SERVER['QUERY_STRING']在 CLI 模式下为空,只适用于 Web SAPI(如 Apache、Nginx + PHP-FPM) - 如果 URL 是伪静态重写过的(比如 Nginx 的
try_files),但没显式传递$args,这个值可能丢失或为空 - 它不会自动解码 URL 编码,比如
%E5%8C%97%E4%BA%AC仍保持原样,需要手动urldecode()
用 parse_str() 解析成关联数组
拿到原始查询字符串后,常用 parse_str() 转成 PHP 数组。它会自动做 URL 解码,并把 & 分隔的键值对映射为变量或数组。
典型用法:
立即学习“PHP免费学习笔记(深入)”;
$query = $_SERVER['QUERY_STRING']; // 'a=1&b=2&c[]=x&c[]=y' $parsed = []; parse_str($query, $parsed); // $parsed === ['a' => '1', 'b' => '2', 'c' => ['x', 'y']]
关键细节:
-
parse_str()不会覆盖已有变量,必须传第二个参数(目标数组),否则结果会写入当前作用域变量,容易引发冲突 - 它支持
[]语法生成数组,也支持[key]语法生成多维键,但不支持 JSON 风格嵌套 - 如果原始字符串里有重复键名(如
a=1&a=2),后面的值会覆盖前面的——除非用[]显式声明为数组
注意 $_GET 和 parse_str() 的行为差异
$_GET 看似是现成答案,但它不是“获取问号后所有参数”的可靠来源:
-
$_GET是 PHP 自动解析并注入的超全局变量,受php.ini中enable_globals、arg_separator.input影响,还可能被框架或路由中间件提前修改 - 它默认对键名和值都做了
urldecode(),但某些特殊编码(如空格用+表示)处理逻辑与parse_str()略有不同 - 如果请求方法不是 GET(比如 POST 请求带 query string),
$_GET依然可用;但若服务器禁用了$_GET(极少见),你就只能靠$_SERVER['QUERY_STRING'] + parse_str() - 它无法还原原始编码格式,比如你无法知道某个值原本是
%20还是+
遇到中文、特殊字符或空值时怎么保真
URL 查询字符串中常见未编码的空格、中文、斜杠、等号等,PHP 默认解析可能出错或截断。要保真处理:
- 始终优先用
$_SERVER['QUERY_STRING']获取原始字节流,避免依赖已解析状态 - 对值做
rawurldecode()而非urldecode(),前者更严格匹配 RFC 3986,能正确处理%20(空格)而非误将+当空格 - 若需保留空值(如
key=或key无等号),parse_str()会把key=当key => '',但key(无等号)会被忽略——这种边缘情况得自己正则拆分 - 涉及安全校验(比如签名比对)时,必须使用原始未 decode 的字符串参与计算,否则哈希不一致
var_dump($_SERVER['QUERY_STRING']) 比翻日志更快——只要确保不是在命令行里跑。











