yii2需配置urlmanager规则与contentnegotiator行为协同工作:启用enableprettyurl,添加通配符路由如'api/.{format}',并在控制器中声明contentnegotiator行为映射application/json和application/xml到对应响应格式。

Yii2 中如何让路由自动识别 .json 和 .xml 后缀
Yii2 默认不自动处理带 .json 或 .xml 后缀的请求,必须显式配置 URL 解析规则和响应格式协商。核心不是“加后缀就能用”,而是让框架知道:这个后缀对应什么内容类型、该走哪个 action、返回时用什么序列化方式。
常见错误现象:404 Not Found(路由没匹配)、500(UnsupportedMediaTypeHttpException)、或返回 HTML 而非 JSON/XML。
- 在
urlManager配置中启用enablePrettyUrl和showScriptName(否则后缀可能被 Web 服务器截断) - 添加带后缀的规则,例如
'api/users.<code>json' => 'api/user/index',但更推荐用通配符统一处理 - 必须配合
ContentNegotiator行为,否则即使 URL 匹配,Response也不会自动设Content-Type
怎么写一个能同时响应 .json 和 .xml 的 action
别在每个 action 里手动判断后缀并 echo 字符串——那样破坏 Yii 的响应生命周期,也绕过异常处理和序列化逻辑。正确做法是:统一由 ContentNegotiator 拦截请求,再交由 Serializer 处理数据输出。
使用场景:RESTful API 接口,如 /v1/posts.json 和 /v1/posts.xml 返回相同数据,仅格式不同。
- 在 controller 类里声明
behaviors(),加入ContentNegotiator,设置formats映射:['application/json' => Response::FORMAT_JSON, 'application/xml' => Response::FORMAT_XML] - 确保
Request对象能从 URL 后缀推导出Accept头:需在urlManager中启用useRequestParameters,或手动在ContentNegotiator的acceptParam设为_format并传参 -
Response::FORMAT_XML要求数据是数组或实现了toArray()的对象;原生对象若无该方法会报错
.json 和 .xml 路由后缀对性能和兼容性的影响
后缀本身不增加计算开销,但隐含两个实际成本:一是多一次正则匹配(URL 规则越多越明显),二是 XML 序列化比 JSON 慢且内存占用高,尤其数据量大时。
兼容性上,.xml 在现代前端调用中基本被弃用;部分代理或 CDN 可能缓存不同后缀为独立资源,导致 .json 和 .xml 版本缓存不一致。
- 避免在规则中写死多个重复路径,比如同时写
'posts.json'和'posts.xml';改用'posts.<code>{format}' +defaults => ['format' => 'json'] - XML 格式需注意特殊字符转义(如
&→&),Yii 的XmlResponseFormatter会处理,但自定义 XML 构建容易遗漏 - 如果只服务前端 JS,其实没必要支持
.xml;保留它只会增加测试和维护负担
为什么加了规则还是返回 404?检查这三处
最常卡在这几个地方,不是配置漏了,就是顺序或作用域错了。
-
urlManager规则写在rules数组里,但放在了hostInfo或baseUrl等非规则字段之后——YII 会忽略后续所有项 - Web 服务器(如 Nginx)把带点的路径当成静态文件,直接 404,没转发给 PHP;需确认 rewrite 规则是否覆盖
.json/.xml - controller ID 或 action ID 拼写错误,比如写了
user/index却把 controller 命名为UserController(正确)写成UsersController(错误)
复杂点在于:URL 后缀、Accept 头、ContentNegotiator 的参数来源、Response 格式设置,这四者要对齐才真正生效。少一个环节,就只是“看起来配了,实际没走通”。











