Yii2 REST 响应格式化指南:Content Negotiation、Serializer 与 JSON/XML 输出控制
后端Web框架【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址https://gitcode.com/gh_mirrors/yi/yii2点击查看免费下载RESTful API 请求处理中响应格式化决定客户端最终收到的数据形态资源对象如何变成数组、数组又如何变成 JSON 或 XML 字符串。本篇以 Yii2 框架的docs/guide/rest-response-formatting.md为骨架结合 framework/rest 下的Controller、Serializer与 framework/web 的Response、JsonResponseFormatter源码完整讲解内容协商Content Negotiation、数据序列化Data Serializing以及 JSON 输出控制三个环节读者可据此掌握响应格式的协商机制、分页信封配置与 JSON 编码调优并能在自己的 API 控制器中落地实践。REST 响应格式化的三个阶段当 Yii2 应用处理一个 RESTful API 请求时与响应格式化相关的步骤通常如下确定影响响应格式的各种因素如媒体类型media type、语言、版本等这一过程即内容协商Content Negotiation将资源对象转换为数组该步骤由 yii\rest\Serializer 完成具体转换规则在 Resources资源 一节中说明将数组按内容协商确定的格式转换为字符串由注册在response应用组件 的 yii\web\Response::formatters 属性中的 yii\web\ResponseFormatterInterface 响应格式化器完成。从源码看yii\rest\Controller的afterAction()会调用serializeData()返回结果而serializeData()使用Yii::createObject($this-serializer)-serialize($data)创建并调用序列化器见 framework/rest/Controller.php随后Response::prepare()根据formatters中对应格式的格式化器将数组数据渲染成响应内容见 framework/web/Response.php。三个阶段由此在控制器与响应对象之间串联成完整的格式化流水线。Content Negotiation 内容协商Yii2 通过 yii\filters\ContentNegotiator 过滤器支持内容协商。RESTful API 基础控制器类 yii\rest\Controller 内置了名为contentNegotiator的过滤器提供响应格式协商与语言协商两种能力。协商过程与典型效果该过滤器在 RESTful API 控制器动作执行前检查请求的Accept请求头并将 yii\web\Response::format 设置为对应格式。例如若请求包含如下请求头Accept: application/json; q1.0, */*; q0.1将得到 JSON 格式的响应$ curl -i -H Accept: application/json; q1.0, */*; q0.1 http://localhost/users HTTP/1.1 200 OK Date: Sun, 02 Mar 2014 05:31:43 GMT Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y X-Powered-By: PHP/5.4.20 X-Pagination-Total-Count: 1000 X-Pagination-Page-Count: 50 X-Pagination-Current-Page: 1 X-Pagination-Per-Page: 20 Link: http://localhost/users?page1; relself, http://localhost/users?page2; relnext, http://localhost/users?page50; rellast Transfer-Encoding: chunked Content-Type: application/json; charsetUTF-8 [ { id: 1, ... }, { id: 2, ... }, ... ]整个流程如下动作执行前ContentNegotiator过滤器检查Accept请求头并把响应格式设置为json动作执行后返回资源对象或集合yii\rest\Serializer将结果转换为数组最后由 yii\web\JsonResponseFormatter 把数组序列化为 JSON 字符串并写入响应体。协商的底层实现要点从 framework/filters/ContentNegotiator.php 的源码可以看到协商的完整逻辑negotiate()会先处理formats若支持多于一种格式自动向响应添加Vary: Accept响应头以利于 HTTP 缓存按Accept头区分缓存若存在formatParam默认_formatGET 参数则优先按该参数直接指定格式参数值合法则直接设置Response::format否则抛出 yii\web\NotAcceptableHttpException状态码 406参数为数组时抛出 yii\web\BadRequestHttpException400无_format参数时遍历$request-getAcceptableContentTypes()按 q 值优先级在formats中匹配 MIME 类型匹配成功则同时设置Response::format、acceptMimeType与acceptParams若所有可接受类型都不匹配会回退到formats中的第一个格式仅当请求中没有*/*通配时才抛出 406 异常。语言协商的逻辑类似languageParam默认_langlanguages支持带键映射与无键前缀回退例如en可匹配en-US、en-GB协商结果写入Yii::$app-language。扩展新格式默认情况下 RESTful API 同时支持 JSON 与 XML 两种格式application/json→json、application/xml→xml见 framework/rest/Controller.php。若需支持新格式可在 API 控制器类中配置contentNegotiator过滤器的 formats 属性use yii\web\Response; public function behaviors() { $behaviors parent::behaviors(); $behaviors[contentNegotiator][formats][text/html] Response::FORMAT_HTML; return $behaviors; }formats属性的键是支持的 MIME 类型值是相应的响应格式名称且该名称必须存在于 yii\web\Response::formatters 中。Response 默认注册的格式包括htmlHtmlResponseFormatter、xmlXmlResponseFormatter、jsonJsonResponseFormatter与jsonpJsonResponseFormatter且useJsonp为true。另外ContentNegotiator既可作动作过滤器使用也可作为应用级的bootstrap组件使用它实现了BootstrapInterface后者可对整个应用生效配置方式参见 framework/filters/ContentNegotiator.php 中的注释示例。Data Serializing 数据序列化yii\rest\Serializer 是负责把资源对象或集合转换为数组的核心组件。它识别实现 yii\base\Arrayable 的对象主要是资源对象以及实现 yii\data\DataProviderInterface 的对象资源集合。serialize() 的分派逻辑从源码 framework/rest/Serializer.php 可以看到serialize()按以下顺序分派若数据是带校验错误的Model$data-hasErrors()为true调用serializeModelErrors()将响应状态码设置为422Data Validation Failed.并输出[{field ..., message ...}, ...]结构的错误数组见 framework/rest/Serializer.php若数据实现Arrayable调用serializeModel()并委托$model-toArray($fields, $expand)若数据实现\JsonSerializable调用jsonSerialize()若数据实现DataProviderInterface调用serializeDataProvider()若数据是数组则递归对每个元素调用serialize()其他类型原样返回。序列化器的fieldsParam默认fields与expandParam默认expand支持客户端通过查询参数控制返回字段getRequestedFields()会把逗号分隔的参数解析为字段列表见 framework/rest/Serializer.php。配置序列化器与 collectionEnvelope可通过设置 yii\rest\Controller::serializer 属性为配置数组来定制序列化器。例如若希望把分页信息直接放进响应体以简化客户端开发可配置 yii\rest\Serializer::collectionEnvelope 属性use yii\rest\ActiveController; class UserController extends ActiveController { public $modelClass app\models\User; public $serializer [ class yii\rest\Serializer, collectionEnvelope items, ]; }之后请求http://localhost/users将得到如下响应HTTP/1.1 200 OK Date: Sun, 02 Mar 2014 05:31:43 GMT Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y X-Powered-By: PHP/5.4.20 X-Pagination-Total-Count: 1000 X-Pagination-Page-Count: 50 X-Pagination-Current-Page: 1 X-Pagination-Per-Page: 20 Link: http://localhost/users?page1; relself, http://localhost/users?page2; relnext, http://localhost/users?page50; rellast Transfer-Encoding: chunked Content-Type: application/json; charsetUTF-8 { items: [ { id: 1, ... }, { id: 2, ... }, ... ], _links: { self: { href: http://localhost/users?page1 }, next: { href: http://localhost/users?page2 }, last: { href: http://localhost/users?page50 } }, _meta: { totalCount: 1000, pageCount: 50, currentPage: 1, perPage: 20 } }可见启用信封后响应体结构变为{ items: [...], _links: {...}, _meta: {...} }其中_links由Pagination::getLinks(true)生成_meta由分页对象的总数、页数、当前页与每页条数组成见 framework/rest/Serializer.php。同时原有分页 HTTP 头X-Pagination-*与Link仍然保留——serializeDataProvider()在返回数据前会调用addPaginationHeaders()写入这些头见 framework/rest/Serializer.php默认头名称由totalCountHeader、pageCountHeader、currentPageHeader、perPageHeader四个属性控制。Serializer 还提供其他实用属性linksEnvelope默认_links与metaEnvelope默认_meta仅在collectionEnvelope设置时生效可自定义信封键名自 2.0.4 起preserveKeys默认false自 2.0.10 起设为true时保留集合数组的键可将集合序列化为以键索引的 JSON 对象而非数组对于HEAD请求serializeModel()与serializeDataProvider()直接返回null从而不产生响应体见 framework/rest/Serializer.php 与第 262-270 行。对应行为在 tests/framework/rest/SerializerTest.php 中有完整的单元测试覆盖可作为理解各种属性组合效果的可执行参考。Controlling JSON Output 控制 JSON 输出JSON 响应由 yii\web\JsonResponseFormatter 生成内部使用 yii\helpers\JsonJSON 助手。该格式化器可在response应用组件的 formatters 属性中配置应用配置参见 concept-configurationsresponse [ // ... formatters [ \yii\web\Response::FORMAT_JSON [ class yii\web\JsonResponseFormatter, prettyPrint YII_DEBUG, // use pretty output in debug mode encodeOptions JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE, // ... ], ], ],常用格式化选项prettyPrint默认false设为true时会在编码选项上追加JSON_PRETTY_PRINT输出易读的格式化 JSON适合开发调试环境如示例中的YII_DEBUGencodeOptions默认值320即JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE见 framework/web/JsonResponseFormatter.php可按 PHP 的json_encode()选项位掩码自由组合例如增加JSON_NUMERIC_CHECK强制数字字符串转为数字contentType自 2.0.14 起支持自定义Content-Type响应头默认按useJsonp取值分别为application/json; charsetUTF-8或application/javascript; charsetUTF-8useJsonp开启 JSONP 模式时要求响应数据是包含data与callback两个成员的数组输出形如callback(data);若数据不满足要求会记录 warning见 framework/web/JsonResponseFormatter.phpkeepObjectType自 2.0.44 起设为true可避免零起始索引的数组被编码为 JSON 数组而是按对象输出与json_encode()行为一致。从 framework/web/JsonResponseFormatter.php 的实现可以看出格式化时若prettyPrint为真则在encodeOptions上按位或JSON_PRETTY_PRINT随后调用Json::encode($response-data, $options)写入$response-contentkeepObjectType在编码前后临时调整Json::$keepObjectType并恢复以避免影响后续请求。关于数值类型的一个关键提醒使用 DAO 数据库层返回的数据一律以字符串形式表示这在 JSON 中并不总是期望的结果——尤其是数值字段本应以数字类型呈现。而使用 ActiveRecord 层获取数据库数据时数值列的值会在 yii\db\ActiveRecord::populateRecord() 中按表结构的列类型进行 PHP 类型转换phpTypecast因此返回的数值字段会成为整数/浮点数从而在 JSON 中正确输出为数字而非字符串。这是选择 DAO 还是 ActiveRecord 输出 API 数据时需要注意的差异点。小结Yii2 的 REST 响应格式化由「内容协商 → 数据序列化 → 格式化器输出」三段流水线构成ContentNegotiator依据Accept头与_format参数确定Response::formatSerializer将资源对象/数据提供器转换为数组并注入分页信息头或信封JsonResponseFormatter/XmlResponseFormatter等格式化器最终把数组渲染为响应体字符串。开发者可通过contentNegotiator的formats扩展媒体类型通过控制器serializer属性定制collectionEnvelope等信封与键保留行为并在response组件中精细控制prettyPrint、encodeOptions等 JSON 编码细节从而构建出格式协商灵活、数据结构可控、编码风格统一的高质量 RESTful API。赞分享后端Web框架【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址https://gitcode.com/gh_mirrors/yi/yii2点击查看免费下载相关推荐Yii2 RESTful API 响应格式化指南内容协商、Serializer 序列化与 JSON/XML 输出控制Yii2 RESTful API 响应格式化指南内容协商、Serializer 序列化与 JSON/XML 输出控制 导读 在 Yii2 中一次 RESTf后端Web框架chatgpt-java响应格式定制ResponseFormat与JSON输出控制chatgpt java响应格式定制ResponseFormat与JSON输出控制 在集成ChatGPT API时你是否遇到过AI返回格式混乱导致解析失败的Autoformer未来展望从Nature Machine Intelligence到下一代时间序列AIAutoformer未来展望从Nature Machine Intelligence到下一代时间序列AI Autoformer作为NeurIPS 2021的创人工智能深度学习机器学习上一篇如何用NLTK分词word_tokenize、Punkt、正则8种分词器实战对比与选型教程下一篇如何把一张发灰的 RAW 救回出片darktable 暗房 6 个关键模块实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Kubernetes 云原生可观察性(Observability)实践指南:指标、日志与追踪三大支柱详解

Kubernetes 云原生可观察性(Observability)实践指南:指标、日志与追踪三大支柱详解

Kubernetes 云原生可观察性(Observability)实践指南:指标、日志与追踪三大支柱详解 【免费下载链接】kubernetes-handbook Kubernetes 架构与生态:从云原生到 AI 原生基础设施的构建指南 项目地址: https://gitcode.com/gh_mirr…

2026/9/24 15:50:04 阅读更多 →
embassy-net-wiznet 0.3.0 演进解读:WIZnet SPI 以太网驱动的多芯片支持与中断寄存器重构

embassy-net-wiznet 0.3.0 演进解读:WIZnet SPI 以太网驱动的多芯片支持与中断寄存器重构

嵌入式物联网异步编程 【免费下载链接】embassy Modern embedded framework, using Rust and async. 项目地址: https://gitcode.com/gh_mirrors/em/embassy 点击查看 免费下载 本文围绕 embassy-net-wiznet 驱动 crate 的版本演进记录(即 embassy-net-…

2026/9/24 15:50:04 阅读更多 →
Docker 启动 Redis 并实现 AOF 与 RDB 持久化(Windows 环境)

Docker 启动 Redis 并实现 AOF 与 RDB 持久化(Windows 环境)

1. 环境准备 本文基于 Windows 10/11 Docker Desktop,目标是在 Windows 上通过 Docker 启动 Redis,并借助宿主机目录挂载实现 RDB、AOF 持久化,避免容器删除后数据丢失。 先确认 Docker 可用。推荐使用 PowerShell 或 Windows Terminal 执行…

2026/9/24 15:49:03 阅读更多 →

最新新闻

bpftrace 贡献指南:从编写工具、RFC 提案到代码合入的完整实践

bpftrace 贡献指南:从编写工具、RFC 提案到代码合入的完整实践

可观测性性能剖析eBPF 【免费下载链接】bpftrace High-level tracing language for Linux 项目地址: https://gitcode.com/gh_mirrors/bp/bpftrace 点击查看 免费下载 bpftrace 是一个面向 Linux 的高层跟踪语言,致力于让开发者用极简的单行命令快速编写…

2026/9/24 17:22:27 阅读更多 →
NetApp FAS8300更换控制器启动中没有发现硬盘

NetApp FAS8300更换控制器启动中没有发现硬盘

本文章介绍NetApp FAS8300更换控制器后,启动的时候未发现硬盘,反复重启。本文章适用于FAS8300和A400, 1、更换控制器后,启动过程未发现硬盘,告警信息如下: WARNING: 0 disks found!Storage Adapters found: 0 Fibre Channel Storage Adapters found! 4 SAS Adapters fo…

2026/9/24 17:22:27 阅读更多 →
Dopamine 经验回放机制深度解析:circular_replay_buffer 模块源码与实战指南

Dopamine 经验回放机制深度解析:circular_replay_buffer 模块源码与实战指南

机器学习深度学习 【免费下载链接】dopamine Dopamine is a research framework for fast prototyping of reinforcement learning algorithms. 项目地址: https://gitcode.com/gh_mirrors/do/dopamine 点击查看 免费下载 导读 dopamine.tf.replay_memory.circul…

2026/9/24 17:22:27 阅读更多 →
GEO服务商能力构成全景:七种定位类型与企业匹配逻辑

GEO服务商能力构成全景:七种定位类型与企业匹配逻辑

2026年,AI搜索正在改变品牌可见性的竞争方式。企业决策者在获取行业信息时,越来越多地直接向AI提问并采纳答案,这个变化使得"品牌是否出现在AI的答案里"成为一个具体问题。市场上的GEO服务商数量在一年内明显增长,类型也…

2026/9/24 17:22:27 阅读更多 →
The Concise TypeScript Book 精讲:Intersection Types(交叉类型)——用 `` 将多个类型组合为一个类型

The Concise TypeScript Book 精讲:Intersection Types(交叉类型)——用 `` 将多个类型组合为一个类型

The Concise TypeScript Book 精讲:Intersection Types(交叉类型)——用 & 将多个类型组合为一个类型 【免费下载链接】typescript-book The Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free an…

2026/9/24 17:22:27 阅读更多 →
Kornia 颜色空间转换指南:YCbCr 与 RGB 互转(rgb_to_ycbcr / ycbcr_to_rgb 函数与模块详解)

Kornia 颜色空间转换指南:YCbCr 与 RGB 互转(rgb_to_ycbcr / ycbcr_to_rgb 函数与模块详解)

计算机视觉人工智能深度学习图像处理 【免费下载链接】kornia 🐍 Geometric Computer Vision Library for Spatial AI 项目地址: https://gitcode.com/gh_mirrors/ko/kornia 点击查看 免费下载 导读 YCbCr 是数字视频与图像压缩(如 JPEG、H…

2026/9/24 17:21:26 阅读更多 →

日新闻

基于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/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

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

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

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

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

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

2026/9/24 14:33:56 阅读更多 →

月新闻

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

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

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

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

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

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

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

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

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

2026/9/24 12:49:17 阅读更多 →