ThinkPHP 6 的 paginate() 必须作用于未执行的查询构造器对象(如 Db::name()->where() 或 Model::where()),不可用于 select() 返回的 Collection 或数组,否则报错 Call to undefined method think\Collection::paginate();正确用法是先构建查询、最后调用 paginate(),并确保模板中使用 {$list} 渲染数据、{$list->render()} 渲染页码。

ThinkPHP 6 的 paginate() 必须配合数据库查询对象调用
直接对数组或集合调用 paginate() 会报错:Call to undefined method think\Collection::paginate()。分页不是“给数据就能分”,而是由查询构造器(Db::table() 或模型的 where() 链式调用)返回的 Query 对象才支持该方法。
正确姿势是:先构建查询,再在末尾加 paginate(),它会自动处理 COUNT 和 LIMIT,并注入分页信息到模板变量中。
-
Db::name('user')->where('status', 1)->paginate(10)✅ -
UserModel::where('status', 1)->paginate(10)✅ -
UserModel::select()->paginate(10)❌(select()返回的是Collection) -
array_slice($data, 0, 10)+ 手动算总数 → 不推荐,绕过框架分页机制,丢失render()和参数自动绑定
控制器里传给模板的变量名必须是 $list(或显式指定)
ThinkPHP 模板引擎默认查找名为 $list 的变量来渲染分页数据。如果你写成 $users 或 $data,{$list|raw} 在模板里会为空,且 {$list->render()} 直接报错。
除非你在 paginate() 时用参数覆盖默认变量名(不常用),否则控制器必须赋值给 $list:
// 控制器方法
public function index()
{
$list = UserModel::where('deleted_at', null)->paginate(15);
return view('', compact('list'));
}
- 使用
compact('list')是最简方式;写['list' => $list]也行 - 如果用了自定义变量名,比如
$users = ...->paginate(15, false, ['var_page' => 'p']),那模板里就得用{$users->render()},且 URL 分页参数变成?p=2 - 别漏掉
compact()—— 常见错误是只写了$list = ...却没传进view()
paginate() 的三个关键参数顺序不能错:每页数量、是否显示渲染 HTML、配置数组
ThinkPHP 6.0+ 的 paginate() 签名是:paginate(int $listRows = 15, bool $simple = false, array $config = [])。很多人把第二个布尔值当成“是否启用分页”,结果传 true 却发现样式没了——其实那是“简易模式”,只返回上一页/下一页链接,不显示数字页码。
-
paginate(10)→ 完整分页(带 1 2 3 …) -
paginate(10, true)→ 简易分页(只有 « 上一页 / 下一页 ») -
paginate(10, false, ['page' => 'p'])→ 完整分页,但 URL 参数用?p=2而非默认?page=2 - 第三个参数里
'query'可追加额外 GET 参数,比如搜索条件:['query' => request()->only(['keyword', 'type'])],避免翻页时丢失筛选条件
模板里必须同时用 {$list} 渲染数据 + {$list->render()} 渲染页码条
只写 {:dump($list)} 看得到数据和分页元信息(如 last_page、current_page),但前端用户看不到页码;只写 {$list->render()} 则页面空荡荡——因为 render() 只输出 HTML 分页控件,不输出数据本身。
标准模板片段(以 TP6 默认模板引擎为例):
{volist name="list" id="vo"}
<p>{$vo.name} - {$vo.email}</p>
{/volist}
<div class="pagination">
{$list->render()}
</div>
-
{volist}迭代的是$list的数据部分(即$list->items()),不是整个分页对象 -
{$list->render()}输出的是带样式的,需配合 CSS;若想自定义 HTML 结构,可用- ...
{$list->render('bootstrap')}或继承think\Paginator重写render() - 注意:模板里不能用
{$list->toArray()},会破坏分页上下文;要取总数用{$list->total()},当前页用{$list->currentPage()}
分页看似简单,但卡点往往在“查询对象没链对”“变量名没对上”“参数顺序搞反”这三处。只要确保 paginate() 是查完立刻调、变量叫 $list、模板里两处都写全,基本不会出问题。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











