ThinkPHP 3.2.x 分页中文参数乱码主因是 U() 函数与手动 urlencode() 叠加导致双重编码,以及 IIS 对路径式 URL 解析异常;应改用 $this->url = U(ACTION_NAME).'?'.http_build_query($this->parameter) 统一由 http_build_query 编码并强制问号传参格式。

ThinkPHP 分页链接中含中文参数时,在 IIS 或部分 Nginx 配置下,点击“下一页”后参数变成 %E5%8C%97%E4%BA%AC 类似编码串,但后续控制器里用 $_GET 取到的却是乱码(如 å%8C%97ä%BA%AC),根本不是原始中文——这不是数据库或模板渲染问题,而是分页类拼 URL 时对编码处理不当导致的双重解码或漏编码。
Page.class 中 U() 拼接 URL 会丢弃原始编码
ThinkPHP 3.2.x 的 Page.class.php 默认用 U(ACTION_NAME, $this->parameter) 生成分页链接,而 U() 内部会对数组参数自动调用 urlencode()。但问题在于:如果控制器传入的 $this->parameter 已是手动 urlencode() 过的值(比如搜索关键词 北京 → %E5%8C%97%E4%BA%AC),U() 会再套一层编码,变成 %25E5%258C%2597%25E4%25BA%25AC,浏览器最终解码一次就错。
- 不要在传参前自己
urlencode(),让U()统一处理原始值 - 若必须预编码(如前端 JS 用
encodeURIComponent()),则分页类里要跳过U(),改用http_build_query() - 修改位置:
ThinkPHP\Library\Think\Page.class.php中show()方法内
IIS 下分页链接含 / 路径风格触发 URL 解析异常
IIS 对 URL 中的 / 后接中文参数特别敏感,例如 /search/index/p/2?keyword=北京 容易把 北京 当作路径段解析并错误转码;而 /search/index?p=2&keyword=北京(问号开头)则稳定得多。
- 强制分页链接走
?key=value形式,避开路径式传参 - 将原
$this->url = U(ACTION_NAME, $this->parameter);替换为:$this->url = U(ACTION_NAME) . '?' . http_build_query($this->parameter);
- 注意:不能直接拼
&,http_build_query()自动处理键值编码和分隔符
中文参数被浏览器或服务器多解一次
典型现象:URL 地址栏显示 keyword=%E5%8C%97%E4%BA%AC,但 $_GET['keyword'] 却是 å%8C%97ä%BA%AC。这是因为 Apache/Nginx + PHP CGI 模式下,某些配置会让服务器在交给 PHP 前先解一次码,PHP 又解一次,造成损坏。
立即学习“PHP免费学习笔记(深入)”;
- 检查
$_SERVER['QUERY_STRING']和$_GET是否一致,不一致说明中间层已干预 - 禁用 Nginx 的
merge_slashes off或 Apache 的AllowEncodedSlashes On等危险配置 - 统一使用
rawurlencode()替代urlencode()编码参数值(前者不把空格转+,更符合 RFC)
真正关键的不是“怎么让中文显示出来”,而是“确保从链接生成 → 浏览器请求 → Web 服务器转发 → PHP 接收”这条链路上,中文只被标准解码一次。任何环节擅自多做一次 encode/decode,都会让结果不可控。尤其在混合部署(如 IIS + FastCGI)场景下,连 $_GET 都可能已经失真,这时得靠 file_get_contents('php://input') 或解析原始 QUERY_STRING 来抢救。



















