json_encode 處理中文時常出現 Unicode 轉義(如 \u4e2d\u6587)或直接變成 null,雖然 PHP 5.4+ 新增 JSON_UNESCAPED_UNICODE 選項,但在舊版本或特定編碼環境下仍須相容處理。本文提供兩種經實戰驗證的穩健方案。
urlencode 將中文轉為 ASCII 安全字串json_encode 不會觸發 Unicode 轉義urldecode 還原原始中文內容<?php
/**
* 將陣列中所有字串值進行 urlencode,支援多維陣列遞迴
* @param array $array 待處理陣列
* @return array 處理後陣列
*/
function encodeOperations(array $array): array {
foreach ($array as $key => $value) {
if (is_array($value)) {
$array[$key] = encodeOperations($value); // 遞迴處理子陣列
} else {
// 統一轉為 UTF-8 再 urlencode,避免編碼不一致導致亂碼
$array[$key] = urlencode(mb_convert_encoding($value, 'UTF-8', 'GBK'));
}
}
return $array;
}
// 使用範例
$data = ['name' => '測試', 'desc' => '包含中文的說明'];
$encoded = encodeOperations($data);
$json = json_encode($encoded);
echo urldecode($json); // 輸出:{"name":"測試","desc":"包含中文的說明"}
?>
<?php
/**
* 通用陣列編碼處理器
*/
class ArrayEncoder {
/**
* 遞迴對陣列所有元素執行指定函式
* @param array $array 目標陣列(傳址)
* @param callable $func 處理函式
* @param string|null $toEncoding 目標編碼
* @param string|null $fromEncoding 來源編碼
* @param bool $applyToKeys 是否同時處理鍵名
*/
public static function encodeOperations(
array &$array,
callable $func,
?string $toEncoding = null,
?string $fromEncoding = null,
bool $applyToKeys = false
): void {
foreach ($array as $key => $value) {
if (is_array($value)) {
self::encodeOperations($array[$key], $func, $toEncoding, $fromEncoding, $applyToKeys);
} else {
// 編碼轉換
if ($toEncoding && $fromEncoding && function_exists('mb_convert_encoding')) {
$value = mb_convert_encoding($value, $toEncoding, $fromEncoding);
}
$array[$key] = $func($value);
}
// 處理鍵名
if ($applyToKeys && is_string($key)) {
$newKey = $func($key);
if ($newKey !== $key) {
$array[$newKey] = $array[$key];
unset($array[$key]);
}
}
}
}
/**
* 陣列轉 JSON(自動處理中文)
* @param array $array 來源陣列
* @param string $encoding 來源編碼(預設 GBK)
* @return string JSON 字串
*/
public static function toJson(array $array, string $encoding = 'GBK'): string {
self::encodeOperations($array, 'urlencode', 'UTF-8', $encoding, true);
$json = json_encode($array);
return urldecode($json);
}
}
// 使用範例
$data = ['標題' => '測試', '內容' => '中文內容'];
echo ArrayEncoder::toJson($data); // 正確輸出中文 JSON
?>
null:通常是字串非 UTF-8 編碼,請先用 mb_convert_encoding($str, 'UTF-8', '原編碼') 轉碼。$a['self'] = &$a),需加入已處理陣列追蹤(如 spl_object_id)避免死迴圈。json_encode($data, JSON_UNESCAPED_UNICODE),效能最佳且原生支援。掌握這兩種方案,無論舊專案維護或新專案開發,都能輕鬆解決 json_encode 中文亂碼難題。