ThinkPHP 6 的 paginate() 必须配合查询构造器使用,不能在模型静态方法结果上调用;需手动处理分页参数、自定义渲染及正确获取总数。

ThinkPHP 6 的 paginate() 必须配合查询构造器使用
直接在模型静态方法(如 User::all())结果上调用 paginate() 会报错或返回空,因为分页需要原始 SQL 查询上下文来生成 COUNT 和 LIMIT 子句。
必须从 Db::table() 或模型的查询构造器(User::where(...))开始链式调用:
$users = User::where('status', 1)->paginate(10);
否则你会看到 Call to undefined method think\Collection::paginate() 这类错误。
自定义分页参数时,list_rows 和 page 不能靠 GET 传参自动识别
ThinkPHP 默认只从 page 参数读取当前页码,但每页条数(list_rows)不会自动从 URL 获取。如果你希望用户能通过 ?page=2&size=20 控制每页数量,得手动提取并传入:
$size = input('size/d', 15);<br>$users = User::paginate($size, false, ['page' => input('page/d', 1)]);
漏掉 false(表示不自动读取 URL 参数)会导致 page 被重复解析,翻页异常。
前端渲染分页 HTML 时,render() 输出的内容依赖模板配置
默认 $users->render() 返回的是 ThinkPHP 内置的 Bootstrap 风格 HTML,但如果项目没引入 Bootstrap CSS,按钮会错位甚至不可见。更关键的是:它不自动适配你自己的分页样式类名。
推荐做法是用 simple() 获取精简结构,再手写 HTML:
{$users->simple()->render()}
或者直接遍历 $users->render() 的数据:$users->currentPage()、$users->lastPage()、$users->hasPages() 等,避免样式绑架。
分页后获取总数时,total() 比 count() 更可靠
有人误用 $users->count() 想拿总记录数,结果得到的是当前页数据量(比如 10 条),不是全表匹配总数。
正确方式是:$users->total() —— 它来自分页过程中的 COUNT 查询缓存;$users->lastPage() 也依赖这个值计算。
注意:如果用了子查询或复杂 JOIN,total() 可能不准,此时需手动指定:
User::where(...)->count(); // 单独查一次
然后传给分页的 total 选项。
分页不是套个方法就完事,核心在于理解它背后是「先 COUNT 再 LIMIT」两个 SQL 的协同。最容易被忽略的是:你在控制器里对 $users 做了 toArray() 或 json() 之后,再调 render() 就失效了——对象已经转成纯数组,没了分页上下文。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










