ThinkPHP5.0的paginate()默认不继承GET参数,需显式传入['query' => request()->param()];处理filter[status]等嵌套参数需手动扁平化;paginate必须作用于未执行查询,且需统一page参数名。

ThinkPHP5.0 的 paginate() 默认不携带当前请求的查询参数(如 search=abc、filter[status]=1),点击分页链接时这些参数就丢了。核心原因是它不自动继承 $_GET,必须显式传入。
用 query 配置项带全参数
控制器中调用 paginate() 时,第三个参数传入 ['query' => request()->param()]:
-
request()->param()比$_GET更可靠,能同时获取 URL 查询参数和路由变量(比如伪静态/user/page/2中的隐含参数) - 不要写成
['query' => $_GET],否则伪静态下可能为空 - 示例:
Db::name('user')->where($map)->paginate(15, false, ['query' => request()->param()]);
处理带中括号的复杂参数(如 filter[status])
TP5.0 原生不支持直接 append 数组结构参数,appends() 会把 filter[status] 当作字符串键,导致链接变成 &filter=[status]=1,后端无法识别。
- 手动扁平化参数:用辅助函数把嵌套数组转为合法键名,例如
filter[status]→filter[status] - 再用
appends()追加,记得先去掉page参数避免冲突:$list->appends(array_diff_key($_GET, ['page'])) - 如果项目已升级到 TP6.0.12+,建议迁移到
withQuery(),但 TP5.0 不支持该方法
检查分页对象是否在查询执行前调用
paginate() 必须作用于未执行的查询构造器,不能对已查出的数据再分页:
立即学习“PHP免费学习笔记(深入)”;
- ✅ 正确:
Db::name('user')->where(...)->paginate(...) - ❌ 错误:
Db::name('user')->where(...)->select()->paginate(...)(报错或无效果) - 如果已有数组数据需分页,改用
collection($data)->paginate()或手动切片
确认分页参数名与接收逻辑一致
默认读取 $_GET['page'],若 URL 是 ?p=2 或 /page/2,需主动指定:
- 修改参数名:
paginate(15, false, ['var_page' => 'p']),这样就读$_GET['p'] - 手动传当前页:
['page' => input('p/d', 1)],避免依赖 GET 自动解析 - 配合
query一起用,确保翻页时p=2和其他参数都保留



















