首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

json_encode 防止中文轉義為 Unicode 的最佳實踐方案

     編輯:PHP 相關知識

問題背景

json_encode 預設將非 ASCII 字符(中文、日文等)轉義為 \uXXXX 格式。雖然符合 JSON 標準,但導致:

  • 日誌可讀性差
  • 傳輸體積略增(每中文字符 6 字節 vs 3 字節 UTF-8)
  • 某些老舊系統/語言解析困難

現代解決方案(PHP 5.4+)


$json = json_encode($data, JSON_UNESCAPED_UNICODE);
// 輸出包含原始 UTF-8 中文,不轉義

常用組合:


json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);

歷史版本兼容方案(PHP 5.3 / 5.2)

PHP 5.3(支援匿名函數)


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');
}

PHP 5.2(無匿名函數)


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');
        }
    }
}

原理解析

  1. mb_encode_numericentity 將非 ASCII 字符(≥0x80)轉為數值實體引用(如 〹),這些字符在 JSON 編碼時**不會**被再次轉義
  2. json_encode 處理後,數值實體保持原樣
  3. mb_decode_numericentity 還原為原始 UTF-8 字符

注意事項

  • 需啟用 mbstring 擴展
  • 輸出編碼必須為 UTF-8,否則會出現亂碼
  • PHP 5.4+ 直接使用 JSON_UNESCAPED_UNICODE 最簡潔高效
  • 若需輸出 GBK/GB2312,先 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 版本。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved