Laravel输出俄语符号异常问题排查与解决求助
这问题我之前处理过好几次,大概率是JSON响应编码设置或者数据库连接字符集配置的问题,咱们一步步拆解原因和解决办法:
可能的原因
- Laravel JSON响应默认转义非ASCII字符:Laravel的
json()响应方法默认会把非ASCII字符(比如俄语西里尔字母)转换成\uXXXX这样的Unicode转义序列,这是PHP原生json_encode()的默认行为。 - 数据库连接字符集配置不完整:虽然phpMyAdmin能正常显示,但Laravel的数据库连接可能没正确指定UTF-8字符集,导致读取数据时字符编码出现转换问题。
- 数据库表字符集不一致:如果categories表的字符集不是
utf8mb4,也可能导致存储或读取时的编码异常。
解决方法
1. 调整JSON响应编码,输出原生UTF-8字符
这是最常见的解决点——你说写入英文时正常,说明数据库存储没问题,主要是JSON输出环节转义了字符。
单个响应设置
在返回JSON数据时,添加JSON_UNESCAPED_UNICODE选项:
// 示例:返回categories数据 $categories = Category::all(); return response()->json($categories, 200, [], JSON_UNESCAPED_UNICODE);
全局默认设置(一劳永逸)
如果希望所有JSON响应都自动禁用Unicode转义,可以在App\Providers\AppServiceProvider.php的boot()方法中添加:
use Illuminate\Support\Facades\Response; public function boot() { // 自定义带Unicode支持的json响应宏 Response::macro('jsonRaw', function ($data = [], $status = 200, $headers = [], $options = 0) { return Response::json($data, $status, $headers, $options | JSON_UNESCAPED_UNICODE); }); }
之后在控制器里就可以用return response()->jsonRaw($yourData);来返回带原生UTF-8字符的JSON。
如果想直接覆盖默认的json()方法,在AppServiceProvider的register()方法中扩展响应工厂:
use Illuminate\Contracts\Routing\ResponseFactory; public function register() { $this->app->extend(ResponseFactory::class, function ($factory) { // 重写json方法,默认添加JSON_UNESCAPED_UNICODE $factory->macro('json', function ($data = [], $status = 200, $headers = [], $options = 0) use ($factory) { return $factory->json($data, $status, $headers, $options | JSON_UNESCAPED_UNICODE); }); return $factory; }); }
这样所有原来用response()->json()的地方都会自动输出原生UTF-8字符。
2. 检查并修正数据库连接配置
打开config/database.php,找到MySQL配置项,确保以下参数正确:
'mysql' => [ 'driver' => 'mysql', // 其他配置... 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'options' => extension_loaded('pdo_mysql') ? array_filter([ PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4', ]) : [], ],
utf8mb4比传统utf8更全面,支持包括俄语、emoji在内的所有Unicode字符。
3. 确保数据库表的字符集正确
即使数据库全局配置正确,单个表的字符集也可能不一致。可以用SQL命令修改categories表:
ALTER TABLE categories CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
或者直接在phpMyAdmin中找到该表,修改其字符集和校对规则。
4. 排查代码中的手动转义操作
检查控制器、模型或查询逻辑中,有没有使用addslashes()、htmlspecialchars()这类会转义非ASCII字符的函数,如果有,去掉这些不必要的转义处理。
验证方法
修改完成后,重启Laravel服务(如果用了配置缓存,记得执行php artisan config:clear),重新请求接口就能看到正常的俄语字符Обувь,而非Unicode转义序列了。
内容的提问来源于stack exchange,提问作者Manuchekhr

