首页/新闻资讯/正文详情

Yii2 REST 响应格式化指南:Content Negotiation、Serializer 与 JSON/XML 输出控制

发布时间:2026/9/24 15:50:07 来源:云帆数科 栏目:资讯中心
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:07

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:07

云手机原理与 Python 自动化实战:ADB 单机到百台群控,附傲晨云手机选型建议
云手机原理与 Python 自动化实战:ADB 单机到百台群控,附傲晨云手机选型建议

摘要:云手机不是“模拟器上云”这么简单,它的本质是把 Android 实例资源化。本文先讲清云手机的 ARM 虚拟化、容器隔离、ADB 控制通道、WebRTC 推流四大件,再用 Python 演示单机装包/启动/截图、UI 自动化、批量并发群控,最后结合… · 2026/9/24 15:50:07

Boto3 从 Python 2 迁移到 Python 3:官方升级指南与源码级解读
Boto3 从 Python 2 迁移到 Python 3:官方升级指南与源码级解读

后端云原生 【免费下载链接】boto3 AWS SDK for Python (Boto3) 项目地址: https://gitcode.com/gh_mirrors/bo/boto3 点击查看 免费下载 本指南以 AWS SDK for Python(Boto3)官方迁移文档(docs/source/guide/migrationpy3.rst&a… · 2026/9/24 16:26:12

Presto SHOW STATS 命令完全指南:表与查询的列统计信息查看
Presto SHOW STATS 命令完全指南:表与查询的列统计信息查看

大数据数据库后端 【免费下载链接】presto The official home of the Presto distributed SQL query engine for big data 项目地址: https://gitcode.com/gh_mirrors/pre/presto 点击查看 免费下载 本文是 Presto 分布式 SQL 查询引擎中 SHOW STATS 命令的权威技术… · 2026/9/24 16:26:12

AI搜索时代品牌隐形掉队:南京工业企业必读的GEO服务商选型指南
AI搜索时代品牌隐形掉队:南京工业企业必读的GEO服务商选型指南

当下企业线上营销正面临一个普遍且棘手的悖论:传统SEO排名稳居首页,AI搜索却彻底“查无此牌”。 南京一位工业除尘设备企业的市场负责人老张,近期遇到典型困境:在DeepSeek搜索「南京做工业除尘设备的厂家哪家靠谱」,AI… · 2026/9/24 16:26:06

探秘 ApiManager:强大的API管理与测试工具
探秘 ApiManager:强大的API管理与测试工具

探秘 ApiManager:强大的API管理与测试工具 【免费下载链接】ApiManager 接口文档管理工具 项目地址: https://gitcode.com/gh_mirrors/api/ApiManager 在软件开发过程中,API(应用程序接口)是不同组件间通信的关键桥梁。有效… · 2026/9/24 16:26:06

Multi-Loop Collision:当 CI Sweeper 与 PR Babysitter 同时修改同一个 PR——来自 loop-engineering 的真实事故复盘与分支锁解决方案
Multi-Loop Collision:当 CI Sweeper 与 PR Babysitter 同时修改同一个 PR——来自 loop-engineering 的真实事故复盘与分支锁解决方案

人工智能AI AgentAgent 工作流CLI研发协作AI 技能MCP 服务 【免费下载链接】loop-engineering Practical patterns, starters & CLI tools for loop engineering with AI coding agents. Design systems that prompt and orchestrate agents (inspired by Addy Osmani and … · 2026/9/24 16:25:25

TypeScript 交叉类型(Intersection Types)完全指南:用 `` 组合类型、合并对象形状的权威实战手册
TypeScript 交叉类型(Intersection Types)完全指南:用 `` 组合类型、合并对象形状的权威实战手册

TypeScript 交叉类型(Intersection Types)完全指南:用 & 组合类型、合并对象形状的权威实战手册 【免费下载链接】typescript-book The Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free and Ope… · 2026/9/24 16:25:25

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

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

1D-CNN时间序列建模实战:从Conv1d原理到工业落地
1D-CNN时间序列建模实战:从Conv1d原理到工业落地

简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26

柔软的L:汉语语流中被忽视的舌肌张力控制
柔软的L:汉语语流中被忽视的舌肌张力控制

1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码