yii 2.0.48 中 response 默认不自动 json 化,需手动设 format 为 format_json;默认 jsonresponseformatter 不支持中文直出且不处理循环引用等错误;contentnegotiator 和 beforeaction 设 format 均不可靠;调试应以 curl -i 和日志验证响应头与数据合法性。

Yii 2.0.48 中 response 默认不自动 JSON 化,得手动设 format
Yii 2 的 response 组件默认走 HTML 输出,哪怕你 echo json_encode(...),响应头还是 text/html,前端拿不到正确 Content-Type,fetch/fetch-json 会卡住或报错。
必须显式告诉框架:“这次我要返回 JSON”:
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;- 这行得在
return前执行,比如控制器 action 开头或中间 - 设完之后,
return ['name' => 'foo', 'code' => 200];就会自动json_encode+ 设置Content-Type: application/json
用 JsonResponseFormatter 自定义 JSON 输出时要注意编码和错误处理
默认的 JSON 格式器(\yii\web\JsonResponseFormatter)会调用 PHP json_encode(),但没开 JSON_UNESCAPED_UNICODE,中文变 \uXXXX;也不处理资源、循环引用等致命错误。
如果需要更可控的输出,建议重写 formatter:
- 在
config/web.php的components里配:'response' => [ 'class' => 'yii\web\Response', 'formatters' => [ \yii\web\Response::FORMAT_JSON => [ 'class' => 'yii\web\JsonResponseFormatter', 'encodeOptions' => JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES, ], ], ], - 注意:
encodeOptions是 PHP 5.4+ 才支持的选项,Yii 2.0.48 兼容,但低版本 PHP 会忽略 - 如果数据里有
DateTime对象或Resource,json_encode仍会失败并返回false—— Yii 不捕获,结果是空响应体,HTTP 状态码却还是 200
beforeAction 或 as json 行为不能替代 response->format
有人试过在 controller 里加 public function behaviors() 返回 ['as json' => 'yii\filters\ContentNegotiator'],以为能自动协商 JSON;或者在 beforeAction 里设 response->format。这两种做法都有坑:
-
ContentNegotiator行为依赖请求头Accept: application/json,但很多前端(比如 axios 默认、小程序 wx.request)根本不发这个头,协商就失效 -
beforeAction设format是全局生效,万一某个 action 想返回 HTML,就得手动切回来,容易漏、难维护 - 最稳的方式还是在每个要 JSON 的 action 里,第一行明确写
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
调试时看不准响应头?别只信浏览器 Network 面板
Yii 在开发模式下可能加了 X-Debug-Token、X-Powered-By 等头,干扰判断;而且有些中间件(比如 gzip、CORS)会在 response 发出前再改头。
验证是否真输出了 JSON,最可靠的是:
- 用
curl -I http://localhost/xxx看原始响应头,确认Content-Type: application/json - 在 action 末尾加一行:
\Yii::info(\Yii::$app->response->getHeaders()->get('Content-Type'), 'response');,查日志 - 如果返回空白但状态码是 200,大概率是
json_encode失败了 —— 检查返回数组里有没有SimpleXMLElement、mysqli_result、未clone的闭包等非法类型
JSON 输出看着简单,但 Yii 2.0.48 的 response 生命周期里,format 设置时机、formatter 配置、数据合法性三者只要一个没对上,就会静默失败。别跳步,每一步都值得单独验一次。











