Yii2 RESTful分页需继承ActiveController并返回ActiveDataProvider实例,URL带page/per-page参数,重命名参数需配置pagination,元信息需重写serializeData()注入,pageSizeLimit需在behaviors中合理设置。

Yii2 的 RESTful 接口分页,ActiveController 默认就支持,但必须用对数据源、配对参数、处理好响应结构,否则返回全量数据或 400 错误是常态。
为什么 GET /api/users 不分页,始终返回全部数据
最常见原因是控制器没继承 ActiveController,或者 index() 返回的不是 ActiveDataProvider 实例。
- 检查控制器是否继承
ActiveController(不是Controller),否则serializeData()不会识别分页逻辑 -
actions()中要显式启用index,且不能覆盖它返回数组、ArrayDataProvider或已执行all()的结果 - 确保
index()方法里构造的是ActiveDataProvider,且query是未执行的ActiveQuery(如User::find()) - 请求 URL 必须带
page和per-page参数,例如/api/users?page=2&per-page=10;缺任一参数,它会默认 page=1、per-page=20,但若配置了pageSizeLimit限制,可能直接报 400
怎么让分页参数名适配前端传的 offset/limit 或 page_number/page_size
Yii2 分页组件只从 $_GET 读参数,默认认 page 和 per-page。硬改前端不现实,后端适配更可控。
- 在
ActiveDataProvider初始化时,通过pagination配置重命名参数:['pageParam' => 'page_number', 'pageSizeParam' => 'page_size'] - 如果要用
offset/limit,注意:这属于“偏移式分页”,ActiveDataProvider不原生支持;可手动 newPagination实例并传入offset和limit,再塞进ActiveDataProvider,但需自行保证totalCount准确 - 别试图在
urlManager的rules里重写 query string —— Yii2 分页逻辑在request->get()层,路由规则不干预 query 解析
分页响应里怎么加 total、pageCount 等元信息
默认 JSON 响应只有当前页数据,totalCount、pageCount 这类字段不会自动出现,前端分页控件拿不到总页数。
-
ActiveController::serializeData()只序列化$dataProvider->getModels(),元信息藏在$dataProvider->getPagination()和$dataProvider->totalCount里 - 必须重写控制器的
serializeData()方法,在父类返回结果基础上追加:'_meta' => ['totalCount' => $provider->totalCount, 'pageCount' => $provider->getPagination()->getPageCount()] - 如果用了缓存或复杂查询,
totalCount可能不准;建议对超大表加count()缓存,或限制最大页码(如pageSizeLimit => [1, 200])防深翻慢查
per-page 超限报 400 怎么调高上限
默认 per-page 最大值是 50,超出就抛 BadRequestHttpException,错误信息类似 "Per-page parameter must be between 1 and 50."
- 在控制器的
behaviors()中修改pageSizeLimit:'pageSizeLimit' => [1, 200] - 这个配置必须放在
contentNegotiator和authenticator之后的行为链里,否则不生效 - 别设过大(比如 1000+),容易触发内存溢出或 SQL
LIMIT性能问题;真实场景建议前端固定每页条数,后端只校验合理范围
分页不是配个 pageSize 就完事——参数名映射、元信息注入、上限控制、缓存策略,每个环节都可能断在生产环境。尤其 serializeData() 重写和 pageSizeLimit 的行为位置,最容易被忽略。


















