正确调用 paginate() 应在 eloquent 查询构建器上直接链式调用,如 user::where('active', 1)->paginate(15);若已执行 get() 则报错,因返回的是 collection 而非查询构建器。

paginate() 方法怎么调用才不报错
直接在 Eloquent 查询后链式调用 paginate(),不是先 get() 再分页 —— 那样会把全部数据查出来再内存分页,既慢又可能爆内存。
常见错误现象:Call to undefined method Illuminate\Database\Eloquent\Collection::paginate(),就是因为你已经执行了 get() 或 all()。
- 正确写法:
User::where('active', 1)->paginate(15) - 错误写法:
User::where('active', 1)->get()->paginate(15) - 如果必须先取数据(比如用了复杂数组处理),改用
LengthAwarePaginator手动构造,别硬套paginate()
如何自定义分页链接里的参数(比如带搜索关键词)
默认分页链接只保留 page 参数,但实际中你肯定需要把 search、status 这类筛选条件也传下去,否则翻页后搜索就丢了。
用 appends() 最简单,它会自动合并当前请求的所有查询参数:
Users::where('name', 'like', "%{$request->search}%")->paginate(10)->appends($request->except('page'))
注意:不要写 appends(['search' => $request->search]),这样会丢掉其他参数;更别手拼 URL,容易漏转义或冲突。
- 如果只想追加特定几个参数:
appends(['search' => $request->search, 'status' => $request->status]) -
withQueryString()是 Laravel 9+ 新增的快捷写法,效果等同于appends($request->except('page')) - 避免在
appends()里传敏感字段(如password、token),得先except()过滤
前端 Blade 模板里怎么安全渲染分页控件
别自己手写上一页/下一页逻辑,Laravel 的 links() 方法已经处理好所有边界情况(比如第一页不显示上一页、最后一页不显示下一页、移动端适配)。
但默认渲染的 HTML 可能和你的 CSS 框架不匹配(比如 Tailwind、Bootstrap 5),这时别改源码,用 render() + 自定义视图。
- 直接输出:
{{$users->links()}}(Laravel 9+ 默认用 Tailwind 风格) - 指定内置样式:
{{$users->links('pagination::bootstrap-5')}} - 完全自定义:运行
php artisan vendor:publish --tag=laravel-pagination,然后编辑resources/views/vendor/pagination/xxx.blade.php - 注意:如果集合为空(
$users->count() === 0),links()仍会渲染,只是没页码 —— 不需要额外判空
为什么有时候分页总数不准?count() 和 paginate() 结果对不上
根本原因是:当查询包含 GROUP BY、HAVING、复杂 JOIN 或子查询时,Laravel 默认用的 COUNT(*) 统计语句可能无法准确反映分页所需的真实行数。
典型场景:多表关联后去重分页、按聚合结果筛选(比如“订单数 > 5 的用户”)。
- 临时解决:用
simplePaginate()替代 —— 它只查下一页有没有数据,不统计总数,性能好但没“共 XX 条”提示 - 长期方案:手动传入总条数,例如
new LengthAwarePaginator($items, $total, $perPage, $currentPage) - 检查 SQL 日志,看
select count(*)那条是否和主查询逻辑一致;不一致就得重写 count 查询或加withCount()辅助









