paginate()必须在order()之后调用,select()前置会导致分页失效;多字段排序须用二维数组;含函数或join时需显式传count;url排序需通过query参数保留;复合查询应建联合索引。

paginate() 必须链在 order() 之后,不能先 select() 再分页
分页失效、翻页卡死、总数错乱的头号原因:把 select() 放在了 paginate() 前面。ThinkPHP 的 paginate() 不是数组切片工具,它要生成带 LIMIT 和 OFFSET 的 SQL,前提是整个查询链没被提前执行。
正确顺序是:条件 → order() → paginate();错误写法会把全表数据拉进 PHP 再切片,性能崩塌且分页逻辑完全错位。
- ✅ 正确:
Db::name('article')->where('status', 1)->order('id desc')->paginate(10) - ❌ 错误:
Db::name('article')->where('status', 1)->select()->paginate(10)(select()已执行,paginate()只是对数组操作) - 模型同理:
Article::where('is_delete', 0)->order(['status' => 'desc', 'id' => 'desc'])->paginate(8)
多字段排序必须用二维数组,别信一维关联数组
TP5.1+ 和 TP6/8 都明确推荐二维数组写法,因为一维关联数组(如 ['status' => 'desc', 'sort' => 'asc'])在旧版本中可能被键名覆盖或解析异常,尤其当字段名重复或含保留字时。
二维数组能保证字段与方向一一绑定,顺序即优先级,且天然规避键冲突问题。
- ✅ 推荐:
->order([['status', 'desc'], ['sort', 'asc'], ['id', 'desc']]) - ⚠️ 慎用字符串:
->order('status DESC, sort ASC')—— 字段含点号(user.name)、空格或关键字(order)时必须手动加反引号,漏一个就报错 - 最后一个字段建议选唯一字段(如
id),避免相同status和sort值导致分页结果抖动
分页 + order 含函数或 JOIN 时,count 总数容易错
调用 paginate() 时,框架默认会执行一条 COUNT(*) 查询。但如果 order() 里用了表达式(如 convert(name using gbk))或跨表字段(如 profile.level),count 查询不带这些逻辑,就会导致总数和实际列表条数对不上。
这不是 bug,是 SQL 执行阶段差异所致 —— count 不走 ORDER BY,也不解析表达式。
- ✅ 显式传
count参数:paginate(15, false, ['count' => $model->where($where)->count()]) - ✅ 复杂场景(UNION / 子查询 / 窗口函数)直接手写原生 SQL,自己控制 count 和 select 逻辑
- ❌ 避免在
order()中用RAND()、NOW()等非确定性函数,否则每页数据都可能不同
URL 传参排序必须带 query,否则翻页丢失排序条件
模板里写 {$list->render()} 默认只保留 page 参数。如果用户点了“按标题升序”,再点第 2 页,链接里没带 sort=title&order=asc,那第 2 页就按默认规则查了 —— 搜索条件和排序同时消失。
这是静默失效,不报错,但业务逻辑已断。
- ✅ 控制器传参:
paginate(10, false, ['query' => request()->param()]) - ✅ 模板中遍历仍用
{volist name="list" id="item"},分页栏用{$list->render()}即可自动带参 - ✅ 动态排序字段必须白名单校验:
$allow = ['title', 'create_time', 'status']; $field = input('sort') ?: 'id'; $field = in_array($field, $allow) ? $field : 'id';
最常被忽略的是:复合索引没建。order 字段和 where 字段没联合建索引,大数据量下 ORDER BY ... LIMIT 会全表扫描。比如 WHERE status = 1 ORDER BY create_time DESC,就得建 (status, create_time) 索引,而不是单字段索引。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











