paginate() 的 query 参数必须显式传入,否则分页链接丢失非 page 参数;需用 array_diff_key 过滤 request()->param() 中的 page/p,或按 var_page 配置动态取值。

paginate() 的 query 参数必须显式传,否则条件全丢
分页链接里参数消失,不是框架抽风,是你没告诉它要带哪些参数过去。paginate() 不会自动把当前 URL 所有 GET 参数塞进下一页链接。比如访问 ?keyword=php&type=blog&page=2,点“下一页”后变成 ?page=3,keyword 和 type 全没了——这就是漏了 query 配置。
query 是个数组,键是参数名,值是对应值,例如 ['keyword' => $keyword, 'type' => $type]。最省事写法是用 request()->param(),但它会把 page 也包进去,而 paginate() 自己管 page,重复会导致翻页错乱。
- 推荐过滤掉分页相关参数:
array_diff_key(request()->param(), ['page' => '', 'p' => '']) - 如果你改过页码参数名(如设了
'var_page' => 'p'),就别在query里硬写page,统一用input($config['var_page'] ?? 'page')取当前页码 - API 场景(POST/JSON)不能依赖
request()->param(),得手动拼query数组
appends() 是模板层补救,不是控制器首选
$list->appends(['keyword' => $keyword]) 确实能在模板里临时加参数,但它只影响当前 render() 调用,且容易和控制器里的 query 配置冲突。一旦你在控制器里已经配了 query,再在模板里用 appends(),参数会被叠加两次。
- 只在简单场景(比如单个固定参数)且控制器没配
query时才考虑用appends() - 不要在循环里反复调用
appends(),它每次返回新对象,性能浪费 - 用了
simple()模式,appends()依然有效,但不改变原始分页对象的 URL 基础
分页对象转成数组后 render() 就失效
有人为了方便,在控制器里写了 $list = $list->toArray() 或 json($list) 再传给模板,结果 {$list->render()} 报错或输出空字符串——因为 render() 必须作用于原始的 Paginator 对象,转成数组就只剩数据,没有分页元信息了。
立即学习“PHP免费学习笔记(深入)”;
-
assign给模板的变量必须是原始Paginator实例,不能是toArray()、json()或collection包装过的 - 如果需要额外处理数据,建议在模板中遍历
$list->items(),而不是提前转结构 - 调试时可用
dump($list)确认是否还是think\Paginator类型
GET 表单是基础前提,POST 会天然丢失条件
如果搜索表单是 method="post",点击分页链接时根本不会携带任何 POST 数据,request()->param() 必然为空。这不是框架问题,是 HTTP 协议行为。
- 所有带筛选条件的分页页面,搜索表单必须用
method="get" - 前端 URL 参数名要和后端
query数组 key 保持一致,大小写、下划线都需对齐 - 若必须用 POST(如含敏感字段),就得换方案:把条件存 session 或加密后放隐藏域,再由控制器还原为
query数组
真正容易被忽略的是 var_page 和 query 的解耦关系:前者只控制页码参数名,后者负责透传业务参数;两者配置错位,就会出现“能翻页但条件不生效”或“条件生效但页码跳错”的混合故障。



















