thinkphp分页核心是paginate()必须链式调用未执行的查询构造器,不可在select()/all()/get()结果上调用;否则退化为内存切片,总数不准、性能崩塌、翻页空白。

ThinkPHP分页不是调用 paginate() 就完事,核心在于它必须直接链式作用于未执行的查询构造器;一旦提前调用 select()、all() 或 get(),分页就退化成 PHP 数组切片,总数不准、性能崩塌、翻页空白。
为什么 paginate() 必须链式调用,不能对数组分页
常见错误是写成 Db::name('user')->where('status', 1)->select()->paginate(10) 或 UserModel::all()->paginate(10)。这两种写法都已触发数据库查询,返回的是 PHP 数组或 think\Collection 对象,而它们没有 paginate() 方法(会报 Call to undefined method think\Collection::paginate()),或者只是对内存数据做切片——全表数据早被拉进 PHP,COUNT 不走 SQL,total() 偏小甚至为 0。
正确做法是让 paginate() 接管整个查询链,它才会自动生成两条 SQL:COUNT(*) 算总数 + 带 LIMIT 的主查询。
-
Db::name('user')->where('status', 1)->order('id desc')->paginate(15)✅ -
UserModel::where('score', '>', 60)->paginate(10)✅ - 复杂查询如含
join()或子查询时,务必确保关联字段有数据库索引,否则 COUNT 可能变慢
翻页后搜索条件丢失?查 query 参数传没传
带关键词搜索的列表,点“下一页”回到第一页、keyword 消失——90% 是没透传 GET 参数。paginate() 默认只读 $_GET['page'],其他参数(如 ?keyword=abc&type=2)不会自动带上。
安全写法是显式传入 query 配置项:
-
->paginate(10, false, ['query' => request()->param()]):透传全部 GET 参数(注意过滤敏感键如token) -
->paginate(10, false, ['query' => ['keyword' => $keyword, 'type' => $type]]):精准控制,避免注入风险 - 若参数含数组(如复选框多值),
request()->param()能自动处理,手动构造时需确保键名结构一致
模板里怎么取数据和渲染分页 HTML
控制器中用 $this->assign('list', $list) 后,模板里不叫 {$page},也不该调用 toArray() —— 分页对象本身既是数据又是元信息容器。
- 循环数据:
{volist name="list" id="item"}{$item.name}{/volist}(list是你 assign 的变量名) - 输出分页 HTML:
{$list->render()},不是{$list->show()},也不是{$page|raw} - 取总数:
{$list->total()};当前页:{$list->currentPage()};总页数:{$list->lastPage()} - API 场景别直接
return $list,应拆解:['data' => $list->items(), 'total' => $list->total(), 'per_page' => $list->listRows()]
API 分页、POST 请求或自定义页码参数怎么办
paginate() 默认从 $_GET['page'] 读页码,但接口走 POST、JSON body 或 header 时,这个逻辑失效,永远卡在第一页。
必须显式指定页码来源:
-
->paginate(10, false, ['page' => input('p/d', 1)]):把页码参数名改成p,URL 变成?p=2 -
->paginate(10, false, ['page' => input('page/d', 1), 'query' => ['keyword' => $keyword]]):同时支持自定义页码 + 搜索透传 - 若每页条数也想动态传(如
?size=20),记得第二个参数设为false,否则page会被解析两次,导致跳转错乱
最易忽略的其实是「总数统计逻辑」和「URL 参数继承」——前者出问题表现为最后一页空白、页码跳变;后者就是点下一页回到首页、搜索条件消失。这两个点不验证一遍,上线后用户反馈第一句往往是“翻不了页”。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











