PHP json_encode() 強制要求輸入為 UTF-8 編碼。若專案頁面編碼為 GBK(GB2312),直接輸出中文會導致 json_encode 回傳 null 或產生 Unicode 逃逸序列(\uXXXX),前端解析麻煩。
/**
* GBK 環境下輸出 JSON(中文不逃逸)
* @param mixed $value 任意資料
* @param int $options json_encode 選項
* @return string JSON 字串
*/
function tb_json_encode($value, $options = 0) {
return json_encode(tb_json_convert_encoding($value, 'GBK', 'UTF-8'), $options);
}
/**
* GBK 環境下解析 JSON
* @param string $str JSON 字串
* @param bool $assoc 是否轉關聯陣列
* @param int $depth 遞迴深度
* @return mixed 解析後資料
*/
function tb_json_decode($str, $assoc = false, $depth = 512) {
return tb_json_convert_encoding(json_decode($str, $assoc, $depth), 'UTF-8', 'GBK');
}
/**
* 遞迴轉換變數編碼(支援純量、陣列、物件)
* @param mixed $data
* @param string $from 來源編碼
* @param string $to 目標編碼
* @return mixed 轉換後資料
*/
function tb_json_convert_encoding($data, $from, $to) {
switch (gettype($data)) {
case 'integer':
case 'boolean':
case 'float':
case 'double':
case 'NULL':
return $data; // 純量無需轉碼
case 'string':
return mb_convert_encoding($data, $to, $from);
case 'object':
$vars = get_object_vars($data);
foreach ($vars as $key => $val) {
$data->$key = tb_json_convert_encoding($val, $from, $to);
}
return $data;
case 'array':
$result = [];
foreach ($data as $k => $v) {
$newKey = tb_json_convert_encoding($k, $from, $to);
$result[$newKey] = tb_json_convert_encoding($v, $from, $to);
}
return $result;
default:
return $data;
}
}
// GBK 頁面輸出 JSON 給前端 Ajax
header('Content-Type: application/json; charset=gbk');
$data = array('msg' => '中文訊息', 'code' => 200);
echo tb_json_encode($data); // 正常輸出中文,不會變 \u4e2d\u6587
// 接收前端 JSON(前端通常發 UTF-8)
$input = file_get_contents('php://input');
$obj = tb_json_decode($input, true); // 取得 GBK 編碼的陣列
json_encode($data, JSON_UNESCAPED_UNICODE) 直接輸出中文,但前提仍是輸入必須 UTF-8。header('Content-Type: application/json; charset=utf-8') 確保瀏覽器正確解碼。僅適用於無法全站改為 UTF-8 的老舊 GBK 專案維護期過渡使用。新專案請直接採用 UTF-8。