Yii 2 分页实战指南:掌握 Pagination 对象、LinkPager 组件与 REST 分页响应
后端Web框架【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址https://gitcode.com/gh_mirrors/yi/yii2点击查看免费下载分页Pagination是 Web 应用中最常见的需求之一当数据量远超单页展示能力时将数据拆分到多页、每页只加载一小部分既保证了页面响应速度也降低了数据库压力。本篇技术指南以 Yii 2 框架的分页方案为核心完整讲解[[yii\data\Pagination]]对象的三大核心属性、与数据库查询的配合方式、LinkPager分页组件以及手动构建分页链接的方法并结合框架源码与测试用例说明其底层原理。读完本文你将能在控制器与视图中独立实现一套完整、可定制、与 Yii 2 深度集成的前后端分页方案。一、为什么需要分页Yii 2 的分页抽象当数据量大到无法在单页中合理展示时业界通用做法是将其拆分为多个页面每个页面只展示一部分数据这就是分页。Yii 2 使用yii\data\Pagination对象来集中表达一套分页方案的全部信息总共有多少条数据、每页展示多少条、当前处于第几页。它位于 framework/data/Pagination.php实现Linkable接口既能被视图组件消费也能直接输出导航链接。这个对象的设计目标是一次创建、多处复用同一个Pagination实例既可以传给数据库查询计算OFFSET/LIMIT也可以传给分页组件渲染按钮还可以用来生成任意页面的 URL避免了在控制器、视图、模型层各自维护页码状态。二、Pagination 对象的三大核心属性Pagination对象用三个属性完整描述一个分页方案这也是官方文档重点强调的三个概念属性说明默认值totalCount数据条目总数通常远大于单页展示的条目数0pageSize每页包含的数据条目数20page当前页码基于 0即 0 表示第一页0在源码中这三者分别对应 Pagination.php 的public $totalCount 0;、L134 的public $defaultPageSize 20;以及 getPage() 中从请求参数解析当前页码的逻辑。需要特别强调的是page是从 0 开始计数的page 0是第一页page 1是第二页。这与 URL 中用户看到的页码从 1 开始存在差异Yii 会在生成 URL 时自动完成1转换详见第五节。三、实战在控制器中结合数据库查询实现分页3.1 核心代码count offset limit 三步走将Pagination用于数据库查询是官方文档给出的标准用法核心思路是先数总数再切分页。以下代码完整继承自官方指南参见 docs/guide/output-pagination.mduse yii\data\Pagination; // 创建一个 DB 查询来获得所有 status 为 1 的文章 $query Article::find()-where([status 1]); // 得到文章的总数注意此时尚未真正从数据库拉取文章数据 $count $query-count(); // 使用总数来创建分页对象 $pagination new Pagination([totalCount $count]); // 使用分页对象计算出的 offset/limit 来填充查询并取得当前页数据 $articles $query-offset($pagination-offset) -limit($pagination-limit) -all();这段代码的执行流程非常清晰构造查询Article::find()-where([status 1])只构建查询条件不立即执行统计总数$query-count()生成SELECT COUNT(*)语句取得总条数作为totalCount创建分页对象new Pagination([totalCount $count])取当前页数据$pagination-offset和$pagination-limit会根据当前页码实时计算$query-offset(...)-limit(...)-all()最终执行SELECT * ... LIMIT offset, limit。$pagination-offset与$pagination-limit是只读属性其计算逻辑位于 getOffset() 与 getLimit()getOffset()返回当前页码 × 每页条数即$this-getPage() * $pageSizegetLimit()直接返回$pageSize当每页条数小于 1即无限分页时返回-1对应 SQL 中不限制返回行数的语义。3.2 完整的控制器动作示例上述逻辑在真实控制器中通常会与视图渲染结合。Pagination类自身的文档注释见 Pagination.php给出了一个完整范例public function actionIndex() { $query Article::find()-where([status 1]); $countQuery clone $query; $pages new Pagination([totalCount $countQuery-count()]); $models $query-offset($pages-offset) -limit($pages-limit) -all(); return $this-render(index, [ models $models, pages $pages, ]); }这里使用clone $query克隆查询对象用于计数避免count()对原查询对象造成状态污染是官方推荐的安全写法。随后将$models与$pages一并传入视图。3.3 当前页是如何确定的在 3.1 的例子中究竟返回哪一页的数据答案取决于请求中是否带有名为page的查询参数。默认情况下Pagination会尝试从page参数读取当前页码若参数缺失则回退为 0第一页。该逻辑体现在 getPage() 中public function getPage($recalculate false) { if ($this-_page null || $recalculate) { $page (int) $this-getQueryParam($this-pageParam, 1) - 1; $this-setPage($page, true); } return $this-_page; }注意两个细节请求参数中的page按从 1 开始解析内部减 1 后转为从 0 开始的页码解析出的页码会经过 setPage() 的范围校验当页码超出总页数时自动收敛到最后一页小于 0 时收敛为 0避免出现越界页或负页。四、用 LinkPager 组件渲染分页按钮数据取回后还需要让用户能够切换页面。Yii 2 提供了[[yii\widgets\LinkPager]]组件它接收一个Pagination对象自动渲染一栏可点击的页码按钮。官方文档给出的最小用法如下use yii\widgets\LinkPager; echo LinkPager::widget([ pagination $pagination, ]);LinkPager的实现位于 framework/widgets/LinkPager.php其核心渲染逻辑在 renderPageButtons() 中。结合源码可以了解到它的默认行为与常用可配置项属性默认值说明maxButtonCount10最多同时显示的页码按钮数量超出时自动收拢为窗口首/尾页附近展开nextPageLabelraquo;下一页按钮标签设为false可隐藏prevPageLabellaquo;上一页按钮标签设为false可隐藏firstPageLabelfalse首页按钮标签默认不显示lastPageLabelfalse末页按钮标签默认不显示hideOnSinglePagetrue只有一页时自动隐藏整个分页条options[class pagination]分页条外层容器默认ul的 HTML 属性activePageCssClassactive当前选中页按钮的 CSS 类disabledPageCssClassdisabled禁用状态按钮的 CSS 类registerLinkTagsfalse是否在页面head中注册prev/next/first/last的link rel标签从 renderPageButtons() 可以看到当pageCount 2且hideOnSinglePage为true时组件直接返回空字符串按钮窗口的计算则由 getPageRange() 完成它基于maxButtonCount以当前页为中心截取页码范围并在接近首尾时自动平移窗口。另外LinkPager的 init() 会强制校验pagination属性必须被设置否则抛出InvalidConfigException。五、手动构建分页 URLcreateUrl 详解某些场景下如自定义 UI、生成分享链接、REST 响应你需要自己创建指向特定页面的 URL。此时可使用[[yii\data\Pagination::createUrl()]]它接收一个页码参数并返回格式正确的 URL。官方文档示例// 指定要创建的 URL 应使用的路由不指定则使用当前请求的路由 $pagination-route article/index; // 显示: /index.php?rarticle%2Findexpage101 echo $pagination-createUrl(100); // 显示: /index.php?rarticle%2Findexpage102 echo $pagination-createUrl(101);注意createUrl()接收的是从 0 开始的内部页码但 URL 中输出的page参数是从 1 开始的用户页码——传入 100 会生成page101。这个1转换在 createUrl() 中完成if ($page 0 || $page 0 $this-forcePageParam) { $params[$this-pageParam] $page 1; } else { unset($params[$this-pageParam]); }结合 createUrl() 的完整实现其行为还有以下几点值得掌握路由来源route属性未设置时自动使用当前请求的路由Yii::$app-controller-getRoute()保留查询参数URL 会保留当前请求中的其他查询参数如搜索关键词qparams属性可显式指定参与 URL 构建的参数集params未设置时默认取$_GET强制页码参数forcePageParam默认为true即使当前是第一页也会输出page1设为false后第一页 URL 将不含page参数测试用例见 PaginationTest.php每页条数参数当pageSize与默认值不一致时URL 中会附带per-page参数对应pageSizeParam属性从而允许用户通过 URL 调整每页数量绝对 URL第三个参数$absolute true时返回绝对地址常用于 REST 场景。getLinks()方法Pagination.php会基于createUrl()一次性生成self、first、last、prev、next五个导航链接这正是LinkPager注册link标签及 REST 序列化器输出_links的数据来源。六、自定义页码参数名pageParam如果项目出于 SEO 或路由规范考虑不希望使用默认的page查询参数可以通过pageParam属性重命名。官方文档给出的提示如下Tip: 创建分页对象时可以通过配置[[yii\data\Pagination::pageParam|pageParam]]属性来自定义查询参数page的名字。$pagination new Pagination([ totalCount $count, pageParam p, // URL 中显示 ?p2 而非 ?page2 ]);该属性定义于 Pagination.phppublic $pageParam page;。与之配套的还有pageSizeParam默认per-page用于自定义每页条数参数名。修改后getPage()的解析、createUrl()的 URL 生成都会统一使用新的参数名全程无缝切换。七、分页与数据提供器、REST 的联动7.1 ActiveDataProvider 自动分页在实际项目中更常见的做法是使用ActiveDataProvider让框架自动完成分页。yii\data\ActiveDataProvider内部会创建并持有Pagination实例并在 prepareModels() 中自动将分页计算出的limit与offset应用到查询上同时把totalCount回填给分页对象。因此配置化地声明即可获得分页能力$provider new ActiveDataProvider([ query Article::find()-where([status 1]), pagination [ pageSize 20, ], ]);这种模式下无需手动编写count()与offset()/limit()LinkPager直接消费$provider-getPagination()即可。7.2 REST 响应中的分页头信息在 RESTful API 场景下yii\rest\Serializer会利用Pagination在响应中输出标准化的分页信息见 framework/rest/Serializer.phpHTTP 响应头X-Pagination-Total-Count总数、X-Pagination-Page-Count总页数、X-Pagination-Current-Page当前页从 1 开始、X-Pagination-Per-Page每页条数以及Link头中的first/last/prev/next链接见 addPaginationHeaders()响应体当设置了_links与_meta信封时序列化结果中会附带导航链接与totalCount、pageCount、currentPage、perPage元信息见 serializePagination()。这些输出全部复用同一个Pagination对象的getLinks()、getPageCount()、getPageSize()等方法充分体现了该对象一处计算、多方消费的设计价值。八、源码级验证Pagination 的边界行为框架测试套件 tests/framework/data/PaginationTest.php 对上述行为做了系统验证可作为理解边界语义的权威参考URL 生成testCreateUrlcreateUrl(2)生成page3证明内部页码到 URL 页码的1转换传入pageSize时 URL 附带per-page传入自定义params时保留额外查询参数页码校验testValidatePagetotalCount100、pageSize10时setPage(999, true)会被收敛为第 9 页最后一页总页数计算testPageCountpageCount ceil(totalCount / pageSize)如totalCount15、pageSize2时总页数为 8偏移与限制testGetOffset、testGetLimitpageSize2、page2时offset为 4pageSize小于 1 时limit返回-1表示不限制导航链接testGetLinksgetLinks()仅在第一页省略prev、在最后一页省略next且永远包含self/first/last当总页数大于 0 时。九、小结Yii 2 的分页体系以yii\data\Pagination对象为核心向上对接数据库查询offset/limit、分页组件LinkPager、数据提供器ActiveDataProvider与 REST 序列化器向下则通过createUrl()统一输出符合路由规范的页码 URL。掌握三个核心属性totalCount、pageSize、page、两套渲染方式LinkPager组件与手动createUrl以及pageParam/forcePageParam/pageSizeLimit等定制开关即可在 Web 与 REST 场景中构建健壮、可定制且与框架深度一致的分页能力。本文对应的官方指南英文版位于 docs/guide/output-pagination.md中文版位于 docs/guide-zh-CN/output-pagination.md核心实现可进一步研读 framework/data/Pagination.php 与 framework/widgets/LinkPager.php。赞分享后端Web框架【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址https://gitcode.com/gh_mirrors/yi/yii2点击查看免费下载相关推荐Yii 2 数据分页实战指南Pagination 对象与 LinkPager 分页组件全解析Yii 2 数据分页实战指南Pagination 对象与 LinkPager 分页组件全解析 本文以 Yii 2 官方指南 Pagination https:后端Web框架Yii 2 数据分页完整指南Pagination 对象与 LinkPager 组件的实战用法Yii 2 数据分页完整指南Pagination 对象与 LinkPager 组件的实战用法 当单页需要展示的数据量过大时常见的做法是将数据拆分到多个页面后端Web框架Yii 2 分页Pagination完全指南从 DB 查询分页到 LinkPager 分页按钮Yii 2 分页Pagination完全指南从 DB 查询分页到 LinkPager 分页按钮 本指南围绕 Yii 2 框架的 yii\data\Pagi后端Web框架创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Libero SoC v11.8安装与License避坑指南

Libero SoC v11.8安装与License避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 6:37:35 阅读更多 →
AI 把页面写出来以后,程序员真正的考验才开始

AI 把页面写出来以后,程序员真正的考验才开始

“接口已经写好了,能不能顺手做个页面?” 这句话,可能比一个复杂的 SQL 更容易让 Java 后端开发者犯难。接口返回什么,心里有数;页面怎么排、图表怎么接、筛选条件怎么同步、构建配置怎么处理,却是另一套需…

2026/9/24 6:36:35 阅读更多 →
AI 进 3D 世界的主流思路是给它 “装眼睛“,这位独立开发者偏不:不看画面的 AI,反而更便宜

AI 进 3D 世界的主流思路是给它 “装眼睛“,这位独立开发者偏不:不看画面的 AI,反而更便宜

2026 年,文生 3D 的能力跨过了"能用"的门槛。用一段自然语言生成可以走进的 3D 房间,用一张照片补全几何细节,按一个坐标生成可飞行、可切换昼夜的地形,这些在公开演示中都已出现。但一个基础问题被跳过了:这…

2026/9/24 6:36:35 阅读更多 →

最新新闻

使用 X-CUBE-AI 将 ONNX 模型部署到 STM32全流程

使用 X-CUBE-AI 将 ONNX 模型部署到 STM32全流程

1、首先需要生成一个onnx文件,初始模型并没有经过训练。 嵌入式 AI 最耗费精力的往往不是模型训练,而是编译器版本、DFP 支持包、I2C 通信时序、内存对齐、串口重定向这些底层细节。用未经收敛的初始模型先把工程跑通,能确保在进入复杂的算法…

2026/9/24 7:24:02 阅读更多 →
Modbus RTU通讯不稳?别只查硬件,CRC与轮询时序才是隐形杀手

Modbus RTU通讯不稳?别只查硬件,CRC与轮询时序才是隐形杀手

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 7:24:02 阅读更多 →
ZLG USBCANFD-200U CAN FD通信调试全闭环指南

ZLG USBCANFD-200U CAN FD通信调试全闭环指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 7:24:02 阅读更多 →
大模型API开发实操指南:5个核心方法落地AI应用

大模型API开发实操指南:5个核心方法落地AI应用

随着大语言模型技术的成熟,调用模型API进行应用开发已经成为软件开发的标准流程。许多开发者认为大模型开发门槛极高,但实际上,只要掌握正确的工程化方法,普通开发者也能快速构建实用的应用。本文将循序渐进地介绍大模型API开发的…

2026/9/24 7:24:02 阅读更多 →
Agent 工具越多越好吗?如何让模型准确选到该用的工具

Agent 工具越多越好吗?如何让模型准确选到该用的工具

刚开始做 Agent 时,我们通常会不断给它加工具。 查天气,加一个工具;搜网页,加一个工具;查数据库,再加一个;发邮件、读文件、调用业务 API……最后一个 Agent 身上可能挂着几十个,甚…

2026/9/24 7:24:01 阅读更多 →
SG90舵机与电位器闭环控制:从PWM原理到多平台实战

SG90舵机与电位器闭环控制:从PWM原理到多平台实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 7:23:01 阅读更多 →

日新闻

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为…

2026/9/24 0:00:19 阅读更多 →
单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

简介:一份基于单细胞RNA测序数据的细胞类型注释算法研究Python毕业设计源码,针对计算机相关专业正在做毕设或需要项目实战的学习者,可用于课程设计与期末大作业。项目代码完整、经导师指导评审通过,可直接运行,覆盖数据…

2026/9/24 0:00:19 阅读更多 →
C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

第一次在项目里被反射卡住,是在一个老旧的WinForms模块里:几十个类依赖PropertyChanged通知,运行时反射读属性、发通知,每次启动慢半拍不说,一上.NET Native/AOT裁剪模式几乎全面崩盘。后来我把这段逻辑全部改成C#源生…

2026/9/24 0:00:19 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/23 4:49:06 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/23 9:53:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/23 9:53:40 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/23 9:53:40 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/23 9:53:40 阅读更多 →