laravel分页有五种实现方式:一、eloquent模型paginate();二、查询构造器db::table()->paginate();三、无总数的simplepaginate();四、手动数组分页lengthawarepaginator;五、带筛选参数的appends()或withquerystring()。

如果您在 Laravel 应用中处理大量数据列表时发现页面加载缓慢、内存占用过高或分页总数不准,则很可能是未正确使用 paginate() 方法,或在高基数数据场景下未选用合适的分页策略。以下是针对不同场景的多种分页实现方式:
一、基础 Eloquent 模型分页
该方式适用于绝大多数标准列表查询,由数据库直接完成 LIMIT/OFFSET 计算,性能稳定且自动携带总条数、页码链接等元信息。
1、在控制器中直接对模型调用 paginate(),传入每页条数(如 20):
2、确保不提前执行 get()、first() 或 all(),否则将触发 Collection::paginate() 错误:
3、将返回的 LengthAwarePaginator 实例传递至视图:
二、查询构造器分页(DB::table)
当查询涉及多表 JOIN、原始 SQL 条件或无法通过 Eloquent 关系表达时,可使用 DB 门面配合 paginate(),其返回结构与 Eloquent 分页器完全一致,支持 links() 渲染和 appends() 参数透传。
1、使用 DB::table() 构建查询链,并在末尾调用 paginate():
2、注意避免在 whereRaw 或 having 中引入可能导致 SQL_CALC_FOUND_ROWS 失效的语法(如某些子查询):
3、若仅需上/下页导航而无需总页数,可改用 simplePaginate() 提升大数据量下的查询效率:
三、无总数分页(simplePaginate)
当数据总量极大(如千万级用户表),COUNT(*) 查询成为瓶颈时,simplePaginate() 可跳过总记录数统计,仅执行 LIMIT + 1 条查询判断“是否有下一页”,显著降低数据库压力。
1、将 paginate() 替换为 simplePaginate(),参数含义相同:
2、前端 Blade 中仍可调用 {{$users->links()}},但页码栏仅显示“上一页/下一页”,不显示总页数与跳转框:
3、在控制器中判断是否存在下一页应使用 $users->hasMorePages(),而非依赖 lastPage():
四、手动数组分页(LengthAwarePaginator)
适用于数据源非数据库(如 API 响应、缓存数组、CSV 解析结果),需在 PHP 层完成切片并注入分页上下文,避免全量加载至内存后切片导致 OOM。
1、先获取完整数据集(务必控制规模,建议 ≤5000 条):
2、计算当前页码、每页条数及偏移量:
3、使用 array_slice 切出当前页数据,并实例化 LengthAwarePaginator:
五、带筛选条件的分页 URL 构造
用户在搜索或筛选状态下翻页时,若分页链接丢失 search、status 等参数,会导致结果重置。必须显式将非 page 参数追加至分页链接中,否则分页行为脱离业务上下文。
1、使用 appends($request->except('page')) 自动合并全部请求参数(推荐):
2、若需排除敏感字段(如 token、password),应先过滤再追加:
3、Laravel 9+ 可直接使用 withQueryString() 替代 appends($request->except('page')),语义更清晰:











