url参数含下划线等特殊字符被自动转义,是因web服务器或cgi层预处理所致;应检查原始query_string与$_get差异,禁用错误rewrite规则,统一用rawurlencode()编码参数值,校验order字段名白名单,关闭框架自动转换及nginx merge_slashes。

PHP分页中 URL 参数含下划线等特殊字符被自动转义怎么办
PHP 默认开启 magic_quotes_gpc(已废弃)或某些 Nginx/Apache 配置会把 URL 中的 _、%、空格等做预处理,导致 $_GET['page_id'] 变成 page%5Fid 或直接丢失。这不是 PHP 分页逻辑出错,而是参数在到达 PHP 前就被 Web 服务器或 CGI 层“动过手脚”。
实际排查时先确认:用 var_dump($_SERVER['QUERY_STRING']) 看原始查询串是否已损坏;再对比 var_dump($_GET) —— 若二者不一致,问题出在解析层。
- Apache 下检查是否有
AllowEncodedSlashes或mod_rewrite规则误转义 - Nginx 中确保
location块未启用decode类指令(如旧版rewrite的break行为异常) - 禁用所有框架路由中间件后再测试,排除框架自身对
$_GET的二次 decode
分页参数含中文、emoji 或空格时 urlencode() 和 rawurlencode() 怎么选
手动拼分页链接时,必须对参数值做编码,但选错函数会导致解码失败。PHP 的 urlencode() 把空格转成 +,而标准 URI 解析器(包括浏览器地址栏、parse_url())要求空格是 %20;rawurlencode() 严格按 RFC 3986 编码,更安全。
比如分页跳转到:?q=北京+朝阳&page=2,若用 urlencode('北京 朝阳') 得到 %E5%8C%97%E4%BA%AC+%E6%9C%9D%E9%98%B3,中间的 + 会被 $_GET 当作空格还原,但若原始词本就含加号(如搜索 a+b),就会错乱。
立即学习“PHP免费学习笔记(深入)”;
- 统一用
rawurlencode($value)处理每个分页参数值 - 不要对整个 query string 再套一次
rawurlencode(),否则&和=也被编码,链接失效 - 前端 JS 调用
encodeURIComponent()与后端rawurlencode()行为一致,可混用
用 PDO 或 MySQLi 分页时,order by 字段名含下划线被 SQL 注入误杀怎么放行
分页常带 order 和 sort 参数,如 ?order=user_name&sort=desc。若直接拼进 SQL:ORDER BY $_GET['order'],即使过滤了单引号也防不住字段名注入(比如传 user_name, (SELECT password FROM users LIMIT 1))。但又不能简单白名单所有带下划线的字段名——业务表字段可能动态生成。
- 只允许预定义字段名:用
in_array($order, ['user_name', 'created_at', 'status'], true)校验 - 若字段名来自数据库元数据,用正则
/^[a-zA-Z0-9_]+$/限制,且长度不超过 64 字符 - 绝不使用
addslashes()或mysql_real_escape_string()处理字段名——它们对标识符无效 - 优先改用查询构建器(如 Laravel Query Builder 的
orderBy()),它内部会用反引号包裹字段名并跳过用户输入校验
TP5/ThinkPHP 分页类自动处理特殊字符却导致 URL 错乱的原因
ThinkPHP 5.x 的 Paginator 默认调用 url() 方法生成分页链接,该方法会对参数做 urlencode(),但若你手动在模板里再套一层 urlencode(),就会双重编码:比如 用户 → %E7%94%A8%E6%88%B7 → %25E7%2594%25A8%25E6%2588%25B7,PHP 解码一次只剩乱码。
更隐蔽的问题是:TP5 的 Url::build() 在开启 url_common 模式时,会把下划线自动转为驼峰(user_name → userName),导致分页参数名和控制器接收名不一致。
- 关闭 URL 自动转换:配置
'url_convert' => false - 分页链接生成统一走
$list->render(),不要自己拼?page=+http_build_query() - 自定义分页模板时,用
{$vo|rawurlencode}(TP 模板语法)仅对值编码,保留 key 不变
最易被忽略的是:Nginx 的 merge_slashes on 默认开启,当分页 URL 出现双斜杠(如 /page//2)时会静默合并,导致后续参数偏移——务必在 location 块显式写 merge_slashes off 并重启。











