需继承 yii\rest\Controller 并返回数组/模型,配置 request 组件的 JsonParser,依赖 Accept 头协商格式;若需绕过序列化则设 FORMAT_RAW、手动设 Content-Type 并 return json_encode()。

Yii2 里怎么让控制器直接返回 JSON 而不是 HTML?
关键不是“输出 JSON”,而是让 yii\rest\Controller 正确接管响应流程。手动 echo json_encode() 或 Yii::$app->response->format = \yii\web\Response::FORMAT_JSON 都可能绕过 Yii2 的序列化、状态码、Content-Type 设置逻辑,导致前端收不到 Content-Type: application/json 或状态码错乱。
- 必须继承
yii\rest\Controller,而不是yii\web\Controller - 动作方法(如
actionIndex())直接 return 数组或模型对象,不要 echo/print - 确保配置中启用了
json格式解析器:'parsers' => ['application/json' => 'yii\web\JsonParser'](通常在request组件里) - 如果用
curl测试没返回 JSON,先检查请求头是否带Accept: application/json—— Yii2 默认按 Accept 头决定格式,不是无条件吐 JSON
为什么 actionIndex() 返回数组却得到 500 错误?
常见原因是返回了无法被 yii\rest\Serializer 序列化的值,比如资源句柄(mysqli_result)、闭包、或未定义的类实例。Yii2 REST 控制器默认用 Serializer 把返回值转成数组再 JSON 化,中间任何一步失败都会抛 InvalidParamException 或 NotSupportedException。
- 避免返回原始数据库结果集,先用
toArray()或jsonSerialize()显式转换 - 模型对象要确保实现了
fields()或extraFields(),否则可能因访问私有属性报错 - 调试时临时加
Yii::info(print_r($data, true), __METHOD__);看实际返回值结构 - 错误信息通常是
"Calling unknown method: yii\db\ActiveQuery::toArray()"—— 注意是 ActiveQuery 对象没调成 ActiveRecord 实例
如何让单个 action 不走 REST 自动序列化?
比如某个接口需要返回纯字符串、二进制数据,或自定义 JSON 结构(含非标准字段),就得绕过 Serializer。但不能简单 echo,否则 Response 状态码、Header 会丢失。
- 在 action 内部设
Yii::$app->response->format = \yii\web\Response::FORMAT_RAW - 手动设置
Yii::$app->response->headers->set('Content-Type', 'application/json') - return
json_encode($data, JSON_UNESCAPED_UNICODE)—— 注意是 return,不是 echo - 如果还要控制 HTTP 状态码,加
Yii::$app->response->setStatusCode(201) - 这种写法适合导出、回调、Webhook 等特殊场景,日常资源接口不推荐
POST 请求 body 是 JSON 却拿不到参数?
Yii2 默认只从 $_POST 和 URL 查询字符串解析参数,JSON body 默认被忽略。即使你发了 {"name":"test"},$request->post('name') 仍是 null。
立即学习“PHP免费学习笔记(深入)”;
- 确认
request组件已配置'parsers' => ['application/json' => 'yii\web\JsonParser'] - 用
$request->getBodyParams()取 JSON 解析后的数组,不是$request->post() - 如果同时支持表单和 JSON 提交,需自己判断:
if ($request->getContentType() === 'application/json') { $data = $request->getBodyParams(); } - 没配 JsonParser 时错误信息是
"Unsupported media type: application/json",HTTP 状态码 415
RESTful 接口真正麻烦的不是 JSON 输出本身,而是序列化链路上每一环的隐式依赖:Serializer、Model fields、Response format、Accept 头协商、Parser 配置 —— 少一环,就容易在测试环境正常、线上报错,或者前端收不到 Content-Type。










