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

Yii2 REST 响应格式化完全指南:内容协商、数据序列化与 JSON 输出控制

发布时间:2026/9/23 14:53:48 来源:云帆数科 栏目:资讯中心
Yii2 REST 响应格式化完全指南:内容协商、数据序列化与 JSON 输出控制
后端Web框架【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址https://gitcode.com/gh_mirrors/yi/yii2点击查看免费下载本文以 Yii 2 框架当前仓库gh_mirrors/yi/yii2的 REST 响应格式化机制为核心系统讲解 RESTful API 从请求到响应的完整链路ContentNegotiator如何根据Accept头与_format参数决定响应格式、yii\rest\Serializer如何把资源对象与分页集合转换为数组以及JsonResponseFormatter如何精细控制 JSON 输出。读完本文你将能够在 Yii2 项目中自定义 API 响应格式、通过collectionEnvelope把分页信息写入响应体、并通过prettyPrint与encodeOptions精确控制 JSON 编码行为同时掌握框架源码与测试对每条规则的实际印证。REST 响应格式化的三步处理流程当应用处理一个 RESTful API 请求时与响应格式化相关的处理通常分为以下三个步骤对应 rest-response-formatting.md 中的定义确定可能影响响应格式的各种因素例如媒体类型media type、语言、版本等。这一过程在业界被称为内容协商Content negotiation在 Yii2 中由yii\filters\ContentNegotiator过滤器完成。把资源对象转换为数组。这一步由yii\rest\Serializer负责具体规则在 资源Resources 一节中说明。按照内容协商阶段确定的格式把数组转换为字符串。这是注册在response应用组件的[[yii\web\Response::formatters|formatters]]属性中的响应格式化器response formatter实现yii\web\ResponseFormatterInterface的任务。从源码上看这三步与yii\rest\Controller内置的行为behaviors一一对应Controller.php 默认注册了contentNegotiator格式协商、verbFilterHTTP 方法校验、authenticator认证与rateLimiter限流而在 afterAction() 中通过serializeData()调用序列化器最终由response组件的 formatter 输出。因此REST 控制器默认就具备协商格式 → 序列化数据 → 格式化输出的完整能力。内容协商让客户端决定响应格式ContentNegotiator 过滤器的工作方式Yii2 通过yii\filters\ContentNegotiator过滤器支持内容协商。RESTful API 的基类控制器yii\rest\Controller内置了名为contentNegotiator的该过滤器实例。该过滤器同时承担两件事响应格式协商依据 GET 参数_format源码中的formatParam见 ContentNegotiator.php以及 HTTP 请求头Accept决定响应格式应用语言协商依据 GET 参数_langlanguageParam以及Accept-Language请求头决定Yii::$app-language。例如当 RESTful API 请求携带如下请求头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, ... }, ... ]底层发生了什么在 RESTful API 控制器的动作action执行之前yii\filters\ContentNegotiator过滤器会检查请求中的Accept请求头并据此把[[yii\web\Response::format|response format]]设置为json即yii\web\Response::FORMAT_JSON。动作执行完毕返回资源对象或集合后yii\rest\Serializer把结果转换为数组最后yii\web\JsonResponseFormatter把数组序列化成 JSON 字符串并写入响应体。源码 negotiateContentType() 精确呈现了这一流程若 GET 参数_format存在且在formats中直接采用该格式此时Accept头不再参与判断否则解析请求的Accept头getAcceptableContentTypes()按客户端声明的 MIME 类型优先级q 值匹配formats键客户端声明了*/*时允许匹配默认格式若所有被请求的内容类型都不被支持则抛出yii\web\NotAcceptableHttpExceptionHTTP 406。同时需要注意当配置了多个格式时过滤器会自动为响应添加Vary: Accept头negotiate()这是 HTTP 缓存正确性的关键细节语言协商失败时则回退到languages列表中的第一个语言。默认格式与自定义新格式默认情况下RESTful API 同时支持 JSON 与 XML 两种格式。这一点可以从 Controller.php 的contentNegotiator行为配置中得到证实application/json Response::FORMAT_JSON与application/xml Response::FORMAT_XML。要支持新的格式需要在 API 控制器类中配置contentNegotiator过滤器的formats属性例如增加 HTML 格式支持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]]中有对应的格式化器声明。数据序列化Serializer 的核心职责识别两种对象类型如文档所述yii\rest\Serializer是负责把资源对象或集合转换为数组的中心组件。它识别两类对象实现yii\base\Arrayable接口的对象——通常由资源对象如 ActiveRecord 模型实现实现yii\data\DataProviderInterface接口的对象——通常作为资源集合。在 Serializer::serialize() 中序列化顺序清晰可见先处理带校验错误的Model返回 422 与错误列表再处理Arrayable、JsonSerializable、DataProviderInterface最后递归处理普通数组。通过 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 } }序列化器的其他关键配置项深入 Serializer.php 源码你会发现序列化器的可配置能力远比文档示例更丰富collectionEnvelope默认null集合包装键名如上面的items未设置时直接返回资源数组分页信息只通过 HTTP 头暴露。linksEnvelope默认_links与metaEnvelope默认_meta_links与_meta的包装键名仅在设置collectionEnvelope后生效见 serializePagination()。preserveKeys默认false设为true时可保留集合数组键把集合序列化为以键索引的 JSON 对象而非纯数组自 2.0.10 起。fieldsParam/expandParam默认fields/expand客户端可通过查询参数?fields...expand...精确控制返回哪些字段及额外字段getRequestedFields()这在减少网络传输量、实现稀疏字段API 时非常实用。分页响应头X-Pagination-Total-Count、X-Pagination-Page-Count、X-Pagination-Current-Page、X-Pagination-Per-Page及Link头由 addPaginationHeaders() 统一写入这也是上面 curl 示例中响应头信息的来源。校验错误序列化当模型存在校验错误时serializeModelErrors() 会把响应状态码设为 422Data Validation Failed.并返回[{field ..., message ...}, ...]结构的错误数组。HEAD 请求优化对于 HEAD 请求序列化器直接返回null避免无谓的响应体开销。序列化器默认值及上述行为均有测试用例支撑例如 tests/framework/rest/SerializerTest.php 中的testExpand()、testFields()、testSerializeModelErrors()与testSerializeDataProvider()分别验证了fields/expand过滤、错误序列化结构以及数据提供器含分页与preserveKeys的序列化结果。JSON 输出的精细控制JsonResponseFormatter 与可配置选项JSON 格式的响应由[[yii\web\JsonResponseFormatter|JsonResponseFormatter]]类生成它内部使用[[yii\helpers\Json|JSON 助手类]]。该格式化器提供了丰富的可配置选项例如$prettyPrint开发阶段非常有用开启后输出带缩进的可读 JSON内部会追加JSON_PRETTY_PRINT编码选项$encodeOptions用于精细控制 JSON 编码行为最终透传给 PHP 的json_encode()。此外从 JsonResponseFormatter.php 源码还可以看到更多可选项$useJsonp默认false开启后输出 JSONP要求响应数据为含data与callback两个键的数组Content-Type相应变为application/javascript; charsetUTF-8formatJsonp()$contentType自 2.0.14 起自定义响应的Content-Type头也可直接使用内置常量CONTENT_TYPE_JSON、CONTENT_TYPE_JSONP或 HAL 风格的CONTENT_TYPE_HAL_JSON$keepObjectType自 2.0.44 起控制零索引键对象是否被编码为数组json_encode()的默认行为不设置时跟随Json::$keepObjectType的取值formatJson()。在应用配置中覆盖格式化器response应用组件的formatters属性可以在应用配置中配置例如response [ // ... formatters [ \yii\web\Response::FORMAT_JSON [ class yii\web\JsonResponseFormatter, prettyPrint YII_DEBUG, // 调试模式下输出易读的 pretty 格式 encodeOptions JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE, // ... ], ], ],注意encodeOptions的默认值就是JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE即十进制 320见 JsonResponseFormatter.php意味着 Yii 默认不转义斜杠与 Unicode 字符prettyPrint默认false。YII_DEBUG常量会在调试模式YII_DEBUGtrue下自动让输出变得易读方便本地开发排错。上述配置行为在 tests/framework/web/JsonResponseFormatterTest.php 中有完整的格式化断言含普通输出与 pretty 输出的对比用例。数据库数值类型与 JSON 输出的一致性在使用 DAO 数据库层返回数据时所有数据都会以字符串形式表示这并不总是符合预期——尤其是 JSON 中数值应有对应的 number 类型而不是字符串123。而当使用 ActiveRecord 层从数据库获取数据时数值列的值会在数据取回阶段被转换为 integer。这一行为与[[yii\db\ActiveRecord::populateRecord()]]相关在 BaseActiveRecord::populateRecord() 中查询结果行的各列值被逐个填充到记录属性中ActiveRecord子类通过覆写该方法如 ActiveRecord.php即可在填充阶段完成类型转换。因此纯 DAO 查询时数值在 JSON 输出中表现为字符串使用 ActiveRecord 时数值列如 int、float 类型字段在填充阶段即被转换为对应的 PHP 数值类型JSON 输出中即为合法的 number。在编写 API 时务必注意这一差异必要时可在 DAO 结果上手动做类型转换以保证 JSON 数值语义的正确性。总结Yii2 的 REST 响应格式化是一条职责清晰的三段式流水线阶段负责组件核心职责内容协商yii\filters\ContentNegotiator依据Accept头与_format参数决定响应格式与语言数据序列化yii\rest\Serializer把资源对象 / 数据提供器转换为数组管理分页头与信封格式化输出yii\web\JsonResponseFormatter等把数组按所选格式编码为响应字符串实践中只需记住几条主线默认支持 JSON/XML可在控制器行为中扩展formats通过serializer属性配置collectionEnvelope即可把_links、_meta分页信息写入响应体通过response组件的formatters配置prettyPrint与encodeOptions可精确控制 JSON 编码最后留意 DAO 与 ActiveRecord 在数值类型上的差异。以上所有行为均可对照 framework/rest、framework/filters/ContentNegotiator.php、framework/web/JsonResponseFormatter.php 源码及其测试用例逐一验证。赞分享后端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框架Yii 2 RESTful API 响应格式化完全指南内容协商、数据序列化与 JSON 输出控制Yii 2 RESTful API 响应格式化完全指南内容协商、数据序列化与 JSON 输出控制 在 Yii 2 框架中RESTful API 的响应格式化后端Web框架jcode Terminal-Bench 2.0 测评实战glibc 兼容构建、Harbor 适配器与可拼接的顺序战役模式jcode Terminal Bench 2.0 测评实战glibc 兼容构建、Harbor 适配器与可拼接的顺序战役模式 本文围绕 jcode 仓库中的 d后端Web框架创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

SAP销售BOM配置实战:四步落地与五大避坑指南
SAP销售BOM配置实战:四步落地与五大避坑指南

简介:本资源是一份面向SAP ABAP开发与SD模块实施顾问的实战型配置指南,聚焦销售BOM(物料清单)在复杂产品组合场景(如盒装综合礼品)中的全流程配置与业务验证。文档系统讲解BOM主数据设置、可用性检查策略&a… · 2026/9/23 14:53:48

LSMW录屏批量上载:SAP数据迁移的兜底方案与实战避坑指南
LSMW录屏批量上载:SAP数据迁移的兜底方案与实战避坑指南

简介:LSMW 是 SAP 数据迁移的核心工具,而 Batch Input Recording 方式特别适合标准化、重复性高的数据上载场景。这份实战操作手册正是围绕该主题展开,面向 SAP 实施顾问、IT 支持人员及需要做数据迁移的运维人员。手册完整覆盖 LSMW 从零到上… · 2026/9/23 14:53:48

管桥专项施工方案:从钻孔灌注桩到满堂脚手架的完整技术指南
管桥专项施工方案:从钻孔灌注桩到满堂脚手架的完整技术指南

简介:面向污水处理厂配套管网建设场景,压缩包内含一份完整的《管桥专项施工方案》,适用于市政给排水、环保工程领域的施工组织、技术交底及安全管控。方案从工程概况出发,明确设计规范和环保要求,并重点展开钻孔灌注桩… · 2026/9/23 14:53:41

腾讯云挂载cfs报错,reboot_mount_tencent_cfs.sh already exists, skipping creation.
腾讯云挂载cfs报错,reboot_mount_tencent_cfs.sh already exists, skipping creation.

这个提示:reboot_mount_tencent_cfs.sh already exists, skipping creation.本身不是报错,意思是腾讯云 CFS 挂载脚本安装过程发现已经存在:reboot_mount_tencent_cfs.sh所以跳过创建真正的问题通常在这条提示前面或后面。需要继续看完整日志… · 2026/9/23 16:19:39

后端老鸟手写Route66路由:保姆级教程避坑指南
后端老鸟手写Route66路由:保姆级教程避坑指南

后端老鸟手写Route66路由:保姆级教程避坑指南 版本升级后 API 全变了?别慌,很多资深后端在面试或重构时都会遇到这种“祖传代码”或“框架升级”的噩梦。今天这篇保姆级教程,不整虚的,直接带你手写一个名为 Route66… · 2026/9/23 16:19:39

GPTQ 集成实战:与 Transformers、PEFT、vLLM、TGI 与 LangChain 的完整对接指南
GPTQ 集成实战:与 Transformers、PEFT、vLLM、TGI 与 LangChain 的完整对接指南

GPTQ 集成实战:与 Transformers、PEFT、vLLM、TGI 与 LangChain 的完整对接指南 【免费下载链接】AI-Research-SKILLs Comprehensive open-source library of AI research and engineering skills for any AI model. Package the skills and your claude code/codex… · 2026/9/23 16:19:39

AIoT边缘计算网关怎么选?从场景出发,找到最匹配的那一款
AIoT边缘计算网关怎么选?从场景出发,找到最匹配的那一款

选型之前,先别急着看参数很多人选边缘计算网关,第一反应是打开规格书,比CPU核心数、比NPU算力、比接口数量。比着比着就乱了——这个型号算力高但串口少,那个型号串口多但没NPU,还有一个什么都好但价格超预算。正确的顺… · 2026/9/23 16:19:32

EA230系列边缘AI计算机选型指南:Jetson Orin Nano 4GB vs 8GB,同样的芯片,差一倍算力?
EA230系列边缘AI计算机选型指南:Jetson Orin Nano 4GB vs 8GB,同样的芯片,差一倍算力?

系列定位:工业AI边缘计算选型指南。写给正在评估Jetson Orin Nano平台的开发者和项目决策者。阅读收益:读完这篇,你能搞清楚Orin Nano 4GB和8GB到底差在哪里,Super Mode能带来多大提升,以及EA230和EA230Pro应该怎么选。… · 2026/9/23 16:19:32

Python图像识别主板质检:模板匹配与特征工程实战
Python图像识别主板质检:模板匹配与特征工程实战

简介:这是一套面向计算机视觉初学者与工业质检方向开发者的主板质量检测系统源码,基于Python与图像识别技术实现,可用于学习缺陷检测、目标检测与关键点识别等典型任务的工程落地。资源包共41个文件,以34个Python脚本为核心&#… · 2026/9/23 16:19:32

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

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

企业微信二维码