ThinkPHP分页通过paginate()方法自动实现,必须由查询构造器(如User::where()或Db::table())链式调用,不可在select()后调用;返回think\Paginator对象,含items()、render()、currentPage()、total()等关键属性,模板中需用{$list->render()}输出分页HTML。

ThinkPHP 的分页不是靠手动计算偏移量和总页数来实现的,而是通过 paginate() 方法自动完成——只要模型或查询构造器支持,一行代码就能生成带分页参数、URL 重写、模板渲染能力的完整分页对象。
怎么在控制器里调用 paginate() 获取分页数据
核心是让查询结果直接调用 paginate(),而不是先 select() 再手动分页。它会自动读取 GET 参数(如 page)并计算当前页、总记录数、每页条数。
- 使用模型时:
UserModel::where('status', 1)->paginate(10),其中10是每页数量 - 使用 Db 查询时:
Db::name('user')->where('status', 1)->paginate(15) - 如果需要自定义参数名(比如把
page改成p):加配置['query' => ['p' => input('p')]] - 注意:不能对已执行
select()的结果再调用paginate(),会报错Call to undefined method think\Collection::paginate()
paginate() 返回的对象里有哪些关键属性
返回的是 think\Paginator 实例(v6)或 think\Paginator\Bootstrap 等具体驱动类,不是普通数组。常用属性有:
-
$list->items():当前页的数据数组(即你要循环渲染的列表) -
$list->render():生成分页 HTML(含上一页/下一页/页码链接),可直接在模板中echo -
$list->lastPage():总页数 -
$list->currentPage():当前页码(从 1 开始) -
$list->total():符合条件的总记录数(用于显示“共 X 条”) - 不要试图用
count($list)获取总条数——它返回的是当前页数据量,不是总数
模板里怎么安全输出分页 HTML 并避免 XSS
render() 默认输出的是带 Bootstrap 样式的 HTML,但如果项目没引入 Bootstrap,或用了其他 UI 框架(如 Layui、Element UI),需要自定义渲染模板。
立即学习“PHP免费学习笔记(深入)”;
- 默认渲染路径是
think\paginator\driver\Bootstrap,对应模板在vendor/topthink/think-orm/src/paginator/driver/bootstrap4.php(v6.1+) - 自定义模板:复制一份该 PHP 文件到
template/paginate/your_style.php,然后在配置中设置'type' => 'YourStyle'和'view_path' => 'template/paginate/' - 模板内所有用户输入(如 URL 参数)必须经过
htmlspecialchars()处理;render()内部已做,但自定义时容易漏掉 - 如果关闭了模板自动转义(
default_filter = htmlspecialchars被删),render()输出的内容需手动echo htmlspecialchars($list->render(), ENT_QUOTES, 'UTF-8')
分页看似简单,但最容易出问题的地方是:在查询链中提前触发了 select() 或 find(),导致 paginate() 失效;还有就是模板里误把 $list 当数组遍历,忘了调用 items()。



















