应启用json_unescaped_unicode选项并确保输入为utf-8编码,统一源数据、脚本文件及http响应头的utf-8设置,配合mb_convert_encoding强制归一化和json_last_error精准排错。

PHP json_encode() 输出中文变成uXXXX
默认情况下 json_encode() 会把 UTF-8 中文转成 Unicode 转义序列(如 "u4f60u597d"),这不是乱码,是标准行为,但前端 JS 解析后显示正常;真出问题往往是后续环节——比如你把 JSON 当普通字符串 echo 出来、没设 Content-Type、或 JS 用错了方式读取。
真正要改的是 json_encode() 的标志位:
- 加
JSON_UNESCAPED_UNICODE才能让中文原样输出("你好"而非"u4f60u597d") - PHP 5.4+ 才支持该常量,低版本只能自己写函数替换
- 别只加这个:建议组合使用
JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK,避免斜杠转义和数字被当字符串
示例:
<?php $data = ['name' => '张三', 'city' => '深圳'];
echo json_encode($data, JSON_UNESCAPED_UNICODE);
// 输出:{"name":"张三","city":"深圳"}
?>
PHP 输出 JSON 时浏览器显示乱码
即使 json_encode() 输出了中文,如果 HTTP 响应头没声明编码,浏览器可能用 GBK 或 ISO-8859-1 解析,导致乱码。
必须显式设置响应头:
- 在
json_encode()前或后加:header('Content-Type: application/json; charset=utf-8'); - 确保 PHP 文件本身是 UTF-8 编码(无 BOM),编辑器里检查下
- 如果走 Ajax,JS 端不用手动解码,
responseType保持默认或设为'json'即可
漏掉 header() 是最常见也最容易忽略的环节。
Miller (mlr) 是一个命令行工具,用于查询、整形和重新格式化名称索引数据,如 CSV、TSV、JSON 和 JSON Lines。它将 awk、sed、cut、join 和 sort 的功能整合到一个专为结构化数据处理而构建的单一工具中。
JS 接收 PHP JSON 后显示为方块或问号
这通常不是 PHP 层的问题,而是前端 JS 没正确处理响应体:
- 用
XMLHttpRequest时,别读responseText后再JSON.parse()——如果响应头没设对,responseText已损坏;优先用responseType = 'json' - 用
fetch()时,直接调res.json(),它会按响应头 charset 自动解码 - 确认 HTML 页面
<meta charset="utf-8">存在,且位置在靠前处
如果 PHP 返回的是纯 JSON 字符串(比如写进一个 <script></script> 标签),更要确保整个 HTML 是 UTF-8,否则 script 内容会被错误解码。
兼容旧版 PHP(
JSON_UNESCAPED_UNICODE 不可用,就得绕过 —— 本质是把转义后的 Unicode 再还原回 UTF-8 字符:
- 先
json_encode(),再用preg_replace_callback()匹配uXXXX并用mb_convert_encoding()还原 - 注意:正则需用
"/\\u([0-9a-f]{4})/i",因为 JSON 字符串里反斜杠是双写的 - 更稳妥的做法是升级 PHP,这类兼容代码容易出边界问题(比如 u0000、代理对)
示例片段:
$json = json_encode($data);
$json = preg_replace_callback('/\\u([0-9a-f]{4})/i', function ($matches) {
return mb_convert_encoding(pack('H*', $matches[1]), 'UTF-8', 'UCS-2BE');
}, $json);
核心就两条:加 JSON_UNESCAPED_UNICODE + 设对 Content-Type。其它环节出问题,往往是因为把“JSON 字符串”当成普通文本去拼接、输出或解析,而忽略了它本应作为结构化数据被整体消费。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










