parse_str直接调用会将键值注入当前作用域导致变量覆盖,必须传入第二个引用参数才能安全获取数组;输入含中文或特殊字符需先urldecode,嵌套结构支持不稳定,复杂场景建议改用json_decode。

parse_str 直接转数组会覆盖变量,必须用第二个参数
默认调用 parse_str 时,它不会返回数组,而是把解析结果直接注入当前作用域为变量——这容易引发命名冲突或意外覆盖。想安全拿到数组,必须传入第二个参数(引用变量),否则得不到结构化数据。
常见错误现象:parse_str("a=1&b=2") 执行后,$a 和 $b 突然出现,但你根本没声明;更糟的是,如果已有同名变量,会被悄悄覆盖。
- 正确写法:
parse_str("a=1&b=2", $output);→$output是['a' => '1', 'b' => '2'] - 不传第二个参数时,函数返回
null,且无任何警告(即使 error_reporting 开启) - 输入字符串里键名含点号(如
a.b=1)或方括号(如a[0]=1),parse_str会尝试构建嵌套结构,但行为不稳定,不建议依赖
中文和特殊字符需要先 urldecode,否则乱码
parse_str 假设输入是已编码的查询字符串(即 key=value 形式,且 value 已经是 urlencode 过的)。如果你传入原始中文字符串(如 "name=张三"),它会把 张 当作未定义字节处理,结果变成乱码或截断。
使用场景:从日志、配置文件或非标准 HTTP 源读取的字符串,往往没经过编码,不能直接喂给 parse_str。
- 安全做法:先
urldecode再解析,例如parse_str(urldecode("name=%E5%BC%A0%E4%B8%89"), $arr) - 如果字符串来自
$_SERVER['QUERY_STRING']或file_get_contents('php://input'),通常已是编码态,可跳过urldecode - 注意:
urldecode对+号转为空格,符合 query string 规范;但若原始字符串用空格代替+,需先str_replace(' ', '+', $str)
替代方案:parse_str 不支持深层嵌套,复杂结构建议用 parse_str + json_decode 组合
当字符串含类似 user[name]=张三&user[age]=25&tags[]=php&tags[]=web 的写法时,parse_str 能生成简单嵌套,但对多层(如 a[b][c]=1)或混合类型(数字索引+关联键)支持脆弱,PHP 版本间行为不一致。
性能影响:parse_str 本身很快,但若反复用于构造深度数组,出错后调试成本高。
- 更可控的做法:用正则或
parse_url+explode先切分键值对,再手动组装数组 - 如果源头可控,改用 JSON 格式传输(如
{"user":{"name":"张三"},"tags":["php","web"]}),然后json_decode($str, true) - 第三方库如
http_build_query的逆向逻辑较重,不推荐只为解析一次而引入
注意 magic_quotes_gpc 和 register_globals 已废弃,但旧代码可能干扰 parse_str 行为
PHP 5.4+ 已移除 magic_quotes_gpc,但如果在兼容老环境(如 PHP 5.2 遗留系统)中运行,开启该选项会导致 parse_str 输入被自动加反斜杠,比如 name=o'reilly 变成 o\'reilly —— 这不是 parse_str 的锅,而是全局过滤在作怪。
容易被忽略的地方:有些框架或 CMS 会在初始化阶段手动模拟类似行为(如对 $_GET 做 addslashes),若你把 $_GET 字符串拼成 query string 再喂给 parse_str,可能重复转义。
- 检查是否启用:
get_magic_quotes_gpc()(仅 PHP - 防御性写法:
parse_str(stripslashes($raw), $out),但仅在确认存在转义时才加 - 现代项目中,应统一关闭所有自动转义,靠 PDO 参数绑定或
htmlspecialchars按需处理
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











