ThinkPHP 6 分页保留搜索条件的关键是 paginate() 的 'query' 配置项传入完整 GET 参数数组,模板中使用 render() 即可自动生成带参数的分页链接;需避免用 empty() 判断导致 0 值丢失,并确保所有搜索字段 assign 到模板以支持回显。

ThinkPHP 6 分页后搜索条件丢失?用 with() 携带查询参数
分页链接默认不保留 GET 参数,点击第2页时搜索关键词就没了。核心是让 paginate() 生成的分页对象知道当前有哪些搜索条件需要透传。
正确做法是在调用 paginate() 前,用 with() 显式注入请求参数:
$where = [];
if ($keyword = $this->request->param('keyword')) {
$where['title'] = ['like', "%{$keyword}%"];
}
$list = ArticleModel::where($where)
->order('id desc')
->paginate(10, false, [
'query' => $this->request->param() // ? 关键:把整个 GET 参数数组传进去
]);
$this->assign('list', $list);
$this->assign('keyword', $keyword);
注意:query 选项必须是数组,且键名要和模板中表单字段名一致(比如 keyword),否则分页链接里不会出现 ?keyword=xxx&page=2。
模板里分页标签不显示搜索条件?检查 url() 和 render() 配合方式
ThinkPHP 的 render() 默认只渲染页码 HTML,不自动拼接 GET 参数。你得确保分页器底层 URL 构建时用了带参数的路由或 URL。
立即学习“PHP免费学习笔记(深入)”;
在模板中,不要直接写 {$list->render|raw} 就完事,需提前设置分页的 URL 生成逻辑:
- 如果用的是原生 URL 模式(
index.php?s=/article/index),上面query参数已足够 - 如果启用了路由(如
route('article/index')),需改用url()手动构造分页链接:
{:url('index', array_merge(input('get.'), ['page' => 1]))}
但更稳妥的做法,是在控制器里统一处理 —— 把 input('get.') 注入到分页配置中,模板里照常调用 render() 即可生效。
多条件搜索(如时间范围、状态下拉)回显失败?避免 empty() 过滤掉 0 或 '0'
常见坑:状态字段值为 0(如“未审核”),用 if ($status = input('status')) 判断会跳过,导致条件丢失、分页链接也不带 status=0。
正确判断方式:
- 用
input('status', '') !== ''或has('status') - 对日期范围等复合参数,建议统一用
input('date_range/a')接收数组,再拆解校验 - 所有搜索字段都应 assign 到模板,即使为空也要传空字符串,保证表单 value 属性能回填
示例:
$status = $this->request->param('status', '');
if ($status !== '') {
$where['status'] = $status;
}
$this->assign('status', $status); // ? 模板 select 的 value 就靠它
使用 layui 或 element-ui 分页组件时 URL 不同步?别绕开 ThinkPHP 分页机制
有人为“好看”弃用 render(),自己用 JS 拼 /article/index?page=2&keyword=abc,结果搜索条件漏传、CSRF 校验失败、缓存错乱。
真实建议:
- 前端分页组件只负责触发跳转,URL 仍由后端生成(比如返回 JSON 里的
next_page_url字段) - 或用
{$list->render('bootstrap')}渲染出兼容结构的 HTML,再用 JS 初始化样式,不重写逻辑 - 切勿在 JS 里手动拼接
keyword——用户可能已修改搜索框但未提交,JS 拿不到最新值
最稳的路径,始终是让分页行为完全由服务端控制,前端只做呈现和交互触发。
回显的本质不是“记住输入框内容”,而是让每次分页请求都携带完整上下文。最容易被忽略的点:忘记给 query 传参、用 == 判空导致数值 0 被过滤、以及在前后端分离场景下擅自接管 URL 构造逻辑。



















