Yii框架开发RESTful接口时出现乱码,本质是请求响应全链路的字符集编码没有统一,需要从数据库、框架配置、响应设置多个维度排查修复。

常见乱码成因分析
RESTful接口乱码通常不是单一环节的问题,常见的成因主要有以下几类:
- 数据库连接的字符集和表字段字符集不一致,查询出来的原始数据已经是乱码
- Yii框架没有正确设置响应头的Content-Type字符集,浏览器或调用端解析时用了错误编码
- 数据序列化过程中字符集被转换错误,比如JSON编码时使用了非UTF-8的编码方式
- 服务端文件本身编码不是UTF-8,导致硬编码的中文内容输出时乱码
分步骤修复操作
1. 统一数据库字符集配置
首先确保数据库、表、字段的字符集都是UTF-8,同时Yii的数据库连接配置要指定字符集。以MySQL为例,修改Yii的数据库配置:
<?php
// config/db.php 数据库配置
return [
'class' => 'yiidbConnection',
'dsn' => 'mysql:host=localhost;dbname=test;charset=utf8mb4', // 这里指定charset为utf8mb4
'username' => 'root',
'password' => '123456',
'charset' => 'utf8mb4', // 额外设置连接字符集
'enableSchemaCache' => true,
];
注意要使用utf8mb4而不是utf8,utf8mb4支持完整的UTF-8字符,包括emoji等特殊符号,避免部分字符无法存储的问题。
2. 配置RESTful响应字符集
Yii的RESTful接口默认使用yiiwebResponse处理响应,需要手动设置响应头的Content-Type编码。可以在应用配置中全局设置,也可以针对接口控制器单独设置。
全局配置方式,在config/web.php中添加:
<?php
// config/web.php
return [
// 其他配置
'components' => [
'response' => [
'class' => 'yiiwebResponse',
'formatters' => [
// 配置JSON格式的响应编码
yiiwebResponse::FORMAT_JSON => [
'class' => 'yiiwebJsonResponseFormatter',
'encodeOptions' => JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT, // 禁止转义中文
],
],
'on beforeSend' => function ($event) {
$response = $event->sender;
// 设置响应头字符集为UTF-8
$response->headers->set('Content-Type', 'application/json; charset=UTF-8');
},
],
],
];
3. 检查控制器返回数据编码
如果接口控制器中手动处理了数据返回,需要确保数据本身是UTF-8编码,不要做多余的编码转换。比如不要在返回前使用iconv或者mb_convert_encoding随意转换编码。
正确的接口返回示例:
<?php
namespace appcontrollers;
use yiirestController;
use yiiwebResponse;
class UserController extends Controller
{
public function actionIndex()
{
Yii::$app->response->format = Response::FORMAT_JSON;
// 直接从数据库查询的数据,只要数据库编码正确,不需要额外转码
$data = [
'code' => 0,
'msg' => '请求成功',
'data' => [
'name' => '张三',
'age' => 20
]
];
return $data;
}
}
4. 验证文件编码
检查所有Yii相关的PHP文件编码是否为UTF-8无BOM格式,很多编辑器默认保存为GBK或者其他编码,会导致硬编码的中文内容输出乱码。可以用编辑器打开文件,查看右下角的编码标识,如果不是UTF-8就转换为UTF-8无BOM格式保存。
修复后验证方法
修复完成后可以用以下方式验证:
- 使用Postman或者curl请求接口,查看响应头的Content-Type是否包含charset=UTF-8
- 查看返回的JSON数据中的中文是否正常显示,没有乱码或者转义后的Unicode字符
- 测试包含特殊符号、emoji的内容是否能正常返回和存储
如果还是出现乱码,可以打印中间环节的数据,比如数据库查询后的原始数据、序列化前的数据,逐步定位是哪个环节编码出现了问题。