Yii::$app->response设置响应需注意:必须显式指定format(如FORMAT_JSON)否则默认为HTML;sendFile()会自动设header,勿手动重复添加;关键状态码应主动setStatusCode而非仅抛异常;send()仅在需立即输出时调用,避免提前或重复触发。

直接用 Yii::$app->response 就能控制输出,但写错位置、漏设 format 或 status、误用 send() 都会导致响应不生效、JSON 乱码、下载失败或状态码被覆盖。
设置 JSON 响应必须显式指定 format
只给 data 赋值数组或对象,浏览器收到的仍是 HTML 格式文本(因为默认 format 是 \yii\web\Response::FORMAT_HTML)。
-
Yii::$app->response->data = ['name' => 'Alice'];→ 返回纯文本,不是 JSON - 必须加一句:
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; - 如果用了自定义 ResponseFormatter,
formatJson()里别做 DB 查询或耗时操作,它在 send 前才执行,拖慢所有接口 - 中文乱码?父类默认没开
JSON_UNESCAPED_UNICODE,自定义 formatter 里要手动补上
文件下载要避免路径和 header 冲突
sendFile() 内部会自动设置 Content-Disposition 和 Content-Type,手动再加 header 容易冲突或覆盖。
-
Yii::$app->response->sendFile('/var/www/html/uploads/a.pdf', '用户协议.pdf');—— 推荐,路径用绝对路径,第二参数是浏览器保存的文件名 - 不要同时写:
Yii::$app->response->headers->add('content-disposition', ...),会和sendFile()内置逻辑打架 - 路径起始点是 PHP 进程工作目录,不是
web/目录;若用相对路径,确保当前目录可控(比如在 console 命令中可能不同) - 文件不存在时,
sendFile()抛出InvalidParamException,需自行 try-catch 处理 404
状态码不能只靠 throw 异常来保证
抛出 NotFoundHttpException 确实能返回 404,但框架错误处理器接管后,可能被全局 error handler 拦截并转成 500(尤其在调试关闭、生产环境未配好时)。
- 关键接口建议主动设码:
Yii::$app->response->setStatusCode(404);或Yii::$app->response->statusCode = 404; - 自定义异常响应(如 API)时,必须在 error handler 中手动同步状态码:
Yii::$app->response->setStatusCode($exception->statusCode ?: 500); - 重定向用
$this->redirect()更安全,它内部会自动设 302 + Location header;手动写headers->add('location', ...)必须配套设statusCode,否则浏览器可能忽略
send() 调用时机决定响应是否被截断
框架默认在控制器执行完自动调用 send(),但提前调用或重复调用会导致后续输出失效、headers 已发送警告、甚至空白页。
- 仅在明确需要“立即输出并终止流程”时才调用:
Yii::$app->response->send(); die(); - 调用后
Yii::$app->response->isSent变为true,再设data或headers无效 - 切勿在 layout 或 view 里调用
send(),控制器还没结束,容易和框架自动 send 冲突 - 调试时发现响应内容缺失一半?先查有没有意外触发了
send()
最易被忽略的是:自定义 ResponseFormatter 必须同时实现 formatJson() 和 formatJsonp(),哪怕空着——漏掉后者,带 callback=xxx 的请求直接 500,连错误日志都难定位。











