订单分页丢失时间筛选条件的根本原因是paginate()默认只识别page参数,不继承其他GET参数,需通过query配置项显式透传start_time、end_time等参数并过滤空值。

订单列表按时间筛选后翻页丢失条件,根本不是分页方法写错了,而是 paginate() 默认只认 page 参数,其他如 start_time、end_time、status 一概不带——你点第二页时 URL 变成 ?page=2,筛选条件全丢了。
为什么搜索分页后回到第一页、条件消失?
这是最常被忽略的底层机制问题:paginate() 不会自动继承当前请求的所有 GET 参数,它只从 $_GET['page'] 读页码,其余参数默认清空。一旦你加了时间范围筛选(比如 ?start_time=2026-05-01&end_time=2026-05-20&status=1),点“下一页”就只剩 ?page=2。
- 错误示范:
$list = Order::where($where)->paginate(15)——$where只作用于本次查询,不参与后续分页链接生成 - 正确做法必须显式透传查询参数,否则 render 出来的每一页链接都不含时间条件
- 用
request()->param()最省事,但要注意过滤敏感字段(如token、password)
如何安全透传时间筛选参数到分页链接?
关键在 paginate() 的第三个参数——config 数组里的 query 键。别用 withQuery() 链式调用(ThinkPHP 6.0+ 已废弃),直接传数组最稳。
- 推荐写法:
->paginate(15, false, ['query' => array_filter(request()->only(['start_time', 'end_time', 'status', 'keyword']))]) -
array_filter()自动剔除空值,避免生成?start_time=&end_time=...这类脏参数 - 如果参数是日期范围,前端传
start_time和end_time,后端要用input('start_time')而非input('get.start_time'),防止被框架自动转换格式 - 千万别写
['query' => request()->param()]全量透传,可能把 CSRF token 或调试参数也带上
时间字段分页的两个隐藏陷阱
订单列表常用 create_time 排序,但直接 order('create_time desc') + paginate() 会埋雷。
立即学习“PHP免费学习笔记(深入)”;
- 重复时间戳:高并发下单,多笔订单
create_time完全一致,LIMIT分页会漏数据或重复展示(尤其深度翻页时) - NULL 值干扰:如果部分订单
create_time为 NULL,ORDER BY create_time DESC会让这些记录固定挤在最后几页,且cursorPaginate()直接报错 - 解决方案:强制补默认值(
ALTER TABLE order MODIFY create_time DATETIME NOT NULL DEFAULT '1970-01-01'),或改用复合排序order('create_time desc, id desc'),确保单调性 - 游标分页更优:
Order::order('id desc')->cursorPaginate(20)—— 主键天然唯一、非空、递增,绕开时间字段所有坑
模板里渲染分页时容易踩的三个点
很多人把 $list->render() 往模板里一丢就完事,结果上线才发现样式错乱、链接失效、总数不准。
- 别对
$list调用toArray()或json()再传给模板——对象转数组后,render()方法就没了 - 模板中取总数必须用
{$list->total()},不是{$list->count()}(后者返回当前页条数) -
{$list->render()}输出的是 HTML 字符串,要用{$list->render()|raw}输出,否则<li>全被转义成文字 - 如果用了自定义分页模板(如
app/view/paginate.tpl),确认config/app.php中'paginate' => ['template' => app_path() . 'view/paginate.tpl']已配置,否则还是走默认 Bootstrap 模板
真正卡住人的从来不是怎么写 paginate(),而是搞不清它什么时候读参数、什么时候算总数、什么时候生成链接——尤其是时间筛选这种动态条件,漏传一个 query 或容忍一个 NULL 时间,线上就表现成“翻页回到首页”或“最后十页全是空”。



















