PHP分页需保留原URL参数:用parse_url和parse_str提取并修改page,array_filter过滤空值,http_build_query自动编码,手动补全fragment,严禁二次编码。

翻页链接里丢失 ?sort=name&page=1 后的其他参数
PHP分页时直接拼 page=2,会导致原始URL里的 sort、category、q 等参数全部消失。根本原因是没做参数合并,只写了新页码,没保留旧查询字符串。
正确做法是:先解析当前URL的查询参数,再用新页码覆盖 page 键,最后重新拼接。别硬拼字符串,也别依赖 $_SERVER['QUERY_STRING']——它可能含重复键或编码异常。
- 用
parse_url($_SERVER['REQUEST_URI'], PHP_URL_QUERY)安全提取查询部分 - 用
parse_str()转成关联数组,避免手动explode('&')拆解 - 修改
$params['page'] = $next_page,再用http_build_query()生成新查询串
http_build_query() 会把空值变成 page=&sort=name,怎么去掉空参数
当某个参数值为 null 或空字符串时,http_build_query() 默认保留键名(如 page=&sort=name),但多数场景下你并不想要这个空 page=。
解决方法是在调用前过滤掉空值:
立即学习“PHP免费学习笔记(深入)”;
$params = array_filter($params, function($v) {
return $v !== '' && $v !== null && $v !== false;
});
注意:array_filter() 默认会重排键名,如果参数含数字键(比如 tags[]=1&tags[]=2),要用 ARRAY_FILTER_USE_BOTH 并手动保留键,否则生成的URL会丢掉数组结构。
中文参数或特殊符号在翻页链接里变乱码
常见现象是点击「第2页」后,q=测试 变成 q=%E6%B5%8B%E8%AF%95%25 或更糟——重复编码两次。这是因为有人对已编码的 $_GET 值又调了一次 urlencode()。
关键原则:parse_str() 解析出的值已是解码后的,直接用;http_build_query() 内部会自动编码,你传进去的必须是原始值,不是 urlencode() 过的。
- 错误:
$params['q'] = urlencode($_GET['q']);→ 导致二次编码 - 正确:直接取
$_GET['q']或从parse_str()结果里读,原样塞进$params - 验证方式:打印
$params['q']看是不是“测试”,而不是“%E6%B5%8B%E8%AF%95”
带锚点或哈希的URL翻页后跳转失效
比如原URL是 /list.php?sort=price#results,翻页生成的链接却丢了 #results,用户点完第2页就回到页面顶部。
因为 parse_url() 默认不返回 fragment(即哈希部分),得显式请求:
$parts = parse_url($_SERVER['REQUEST_URI']); $fragment = $parts['fragment'] ?? ''; // … 构造新URL后,手动加上 '#' . $fragment
另外注意:浏览器不会把哈希发给服务器,所以翻页逻辑本身不用管它,但生成链接时必须补上,否则前端体验断裂。别忘了在 http_build_query() 之后拼接,不是之前。
最易被忽略的是路径动态变化场景——比如从 /admin/users?role=staff 跳到 /admin/users?page=2&role=staff,此时 REQUEST_URI 是完整的,但如果你用了硬编码路径(如 /users?),参数就会丢。永远基于当前请求构造,别猜路径。



















