json_encode 預設將非 ASCII 字符(中文、日文等)轉義為 \uXXXX 格式。雖然符合 JSON 標準,但導致:
$json = json_encode($data, JSON_UNESCAPED_UNICODE);
// 輸出包含原始 UTF-8 中文,不轉義
常用組合:
json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
function json_encode_unicode($data) {
array_walk_recursive($data, function (&$value) {
if (is_string($value)) {
$value = mb_encode_numericentity($value, [0x80, 0xFFFF, 0, 0xFFFF], 'UTF-8');
}
});
return mb_decode_numericentity(json_encode($data), [0x80, 0xFFFF, 0, 0xFFFF], 'UTF-8');
}
function json_encode_unicode_52($data) {
_walk_recursive($data, '_encode_callback');
$json = json_encode($data);
return mb_decode_numericentity($json, [0x80, 0xFFFF, 0, 0xFFFF], 'UTF-8');
}
function _walk_recursive(&$data, $callback) {
foreach ($data as $key => &$value) {
if (is_array($value)) {
_walk_recursive($value, $callback);
} elseif (is_string($value)) {
$value = mb_encode_numericentity($value, [0x80, 0xFFFF, 0, 0xFFFF], 'UTF-8');
}
}
}
mb_encode_numericentity 將非 ASCII 字符(≥0x80)轉為數值實體引用(如 〹),這些字符在 JSON 編碼時**不會**被再次轉義json_encode 處理後,數值實體保持原樣mb_decode_numericentity 還原為原始 UTF-8 字符mbstring 擴展JSON_UNESCAPED_UNICODE 最簡潔高效json_encode(..., JSON_UNESCAPED_UNICODE) 再 iconv('UTF-8', 'GBK', $json)
$data = ['msg' => str_repeat('中文測試', 1000)];
// PHP 7.4 測試
$t = microtime(true);
for ($i=0; $i<1000; $i++) json_encode($data, JSON_UNESCAPED_UNICODE);
echo 'JSON_UNESCAPED_UNICODE: ' . (microtime(true)-$t) . "s\n"; // ~0.08s
$t = microtime(true);
for ($i=0; $i<1000; $i++) json_encode_unicode($data);
echo 'mb_encode workaround: ' . (microtime(true)-$t) . "s\n"; // ~0.45s
原生選項快 **5-6 倍**,強烈建議升級 PHP 版本。