activedataprovider 是 yii2 最稳妥的分页方式,自动处理查询、排序、分页,通过 pagination 配置 pagesize 和参数透传;linkpager 默认不保留非分页参数,需显式配置 params;api 分页应返回 _meta 字段含 totalcount 等信息。

Yii2 中怎么用 ActiveDataProvider 做分页
直接用 ActiveDataProvider 是最常见也最稳妥的方式,它自动集成查询、排序、分页逻辑,不需要手动算总条数或切数组。
关键点在于:它依赖 Query 或 ActiveQuery 实例,分页参数默认从 $_GET['page'] 读取(可配),且会自动在 SQL 层加 LIMIT 和 OFFSET。
-
pageSize控制每页几条,设为20就是每页 20 条 -
pagination数组里可配pageSizeParam(比如改成per-page)来适配前端 URL 参数名 - 如果控制器里没传
page参数,它默认用第 1 页,不会报错也不会跳空页 - 注意:不要在
Query上提前调用all()或count(),ActiveDataProvider会自己处理,否则会多查一次
$query = Article::find()->where(['status' => 1]);
$provider = new ActiveDataProvider([
'query' => $query,
'pagination' => ['pageSize' => 15],
]);
为什么 LinkPager 渲染出的链接不带参数(比如分类 ID)
LinkPager 默认只保留分页相关参数(page、per-page),其他 GET 参数会被丢掉——这是 Yii2 的默认行为,不是 bug。
- 解决方法是在
pagination配置里加route和params,显式透传需要的参数 - 比如当前 URL 是
/article/index?category=3,想让分页链接保持category=3,就得写:'params' => $_GET或更安全地写'params' => ['category' => Yii::$app->request->get('category')] - 如果用了 URL 美化(
urlManager开启),route必须写成实际路由路径,如'route' => 'article/index',不能省略
echo LinkPager::widget([
'pagination' => $provider->pagination,
'options' => ['class' => 'pagination'],
'prevPageLabel' => '上一页',
'nextPageLabel' => '下一页',
]);
手写分页(不用 ActiveDataProvider)时怎么避免 count() 全表扫描
有些场景不适合用 ActiveDataProvider(比如复杂视图、union 查询、ES 数据源),就得自己查总数 + 分页数据。但 count() 容易成为性能瓶颈。
立即学习“PHP免费学习笔记(深入)”;
- 如果表有主键且条件能走索引,
count(*)通常够快;但如果WHERE条件涉及函数、模糊匹配或低选择性字段,就可能慢 - 替代方案:对超大表启用估算行数(MySQL 可查
information_schema.TABLES,但不准);或加缓存(比如把总数缓存 5 分钟) - 更实际的做法是限制最大页码(如
maxPages = 1000),超出后不显示“下一页”,避免用户翻到极深页触发慢查询 - 别在分页逻辑里重复执行同一查询两次(一次 count、一次 limit),应复用
Query对象
分页组件在 RESTful API 里怎么返回总页数和当前页
API 不渲染 HTML,所以不用 LinkPager,而是把分页元信息塞进响应体。
-
$provider->getPagination()返回对象,有totalCount、pageCount、currentPage、pageSize等属性 - 推荐结构:
'_meta' => ['totalCount' => $provider->getTotalCount(), 'pageCount' => $provider->getPagination()->getPageCount()] - 注意:如果接口允许客户端传
page但未校验范围,currentPage可能为负数或超界,建议在 action 里先用$provider->pagination->validatePage($page)检查 - 不要把
offset或limit直接暴露给前端,它们是实现细节;只暴露语义清晰的字段,如page、per_page、total
params 配置和 count() 行为,线上出过不少隐蔽故障。











