Laravel分页需手动处理参数传递、安全校验与渲染:用request()->only()安全追加参数,排序字段和方向须白名单校验,大数据量选simplePaginate,页码键名需显式指定。

分页链接默认只保留 page,搜索词、排序字段、每页条数等参数全被丢掉——这不是 bug,是 Laravel 的安全默认。要让这些参数“跟着翻页走”,必须手动处理,而且得做对三件事:传参、校验、渲染。
appends() 必须显式追加,但不能硬写值
直接写 ->appends(['search' => request('search')]) 很危险:用户没输关键词时,request('search') 返回 null,URL 就变成 ?search=&page=2,既难看又可能干扰后续逻辑。
- 用
request()->only(['search', 'order', 'direction', 'perPage'])安全取值,自动过滤空项 - 如果用了自定义分页视图(比如从 vendor 发布出来的),检查模板里是否写了硬编码的
appends(['page' => $page])—— 这会把你传的业务参数全覆盖掉 - 敏感参数(如
token、api_key)要提前过滤:request()->except('token')
排序字段和方向必须白名单校验
orderBy(request('order'), request('direction')) 看似省事,实则埋雷:前端可任意传 order=id; DROP TABLE users; 或 direction=xyz,轻则报错,重则触发非法列名或慢查询。
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
- 定义允许排序的字段白名单:
$allowedOrders = ['id', 'name', 'created_at', 'email']; - 用
in_array(request('order'), $allowedOrders) ? request('order') : 'id'做兜底 - 方向只接受
'asc'或'desc':in_array(request('direction'), ['asc', 'desc']) ? request('direction') : 'desc'
分页方式选错,性能和功能双崩
数据量大、带 JOIN 或 GROUP BY 时,paginate() 默认执行的 COUNT(*) 可能全表扫描,接口从 200ms 拉到 2s+。
- 后台管理列表需跳转任意页 → 用
paginate($perPage),但记得提供total和lastPage - 移动端「加载更多」或无限滚动 → 改用
simplePaginate($perPage),它不 COUNT,只查LIMIT $perPage + 1条,响应快,但只有上/下一页链接 - API 返回必须结构化:
response()->json(['data' => $items->items(), 'meta' => [...]]),别依赖框架自动塞 HTML 字符串
路由参数和页码键名容易被忽略
默认页码参数叫 page,但你用的是 p 或 current_page?那 paginate(15) 就失效了。
- 第三个参数指定页码键名:
User::paginate(10, ['*'], 'p'),这样?p=3才能跳第 3 页 - 第四个参数可强制当前页码:
paginate(10, ['*'], 'page', 5),适合缓存或队列场景 - 别在
get()或toArray()后调paginate(),会报Call to undefined method ::paginate()










