json_encode 強制輸出 UTF-8,非 UTF-8 字符會被轉為 \uXXXX Unicode 轉義序列。\u4e2d\u6587 或亂碼。<?php
/**
* 將任意編碼數組安全編碼為 JSON 字符串(中文保持可讀)
* 原理:urlencode 所有值 → json_encode → urldecode 還原
*/
function jsonEncodeSafe($array) {
// 遞歸 urlencode 所有標量值
array_walk_recursive($array, function(&$value) {
if (is_scalar($value)) {
$value = urlencode($value);
}
});
$json = json_encode($array);
return urldecode($json);
}
// 使用
$arr = ['title' => '中文標題', 'content' => "換行\n內容"];
$js = jsonEncodeSafe($arr);
// 輸出: {"title":"中文標題","content":"換行\n內容"} (中文可讀,換行保持)
?>
<script>
// PHP 直接輸出到 JS 變量
var data = <?= jsonEncodeSafe($arr) ?>;
console.log(data.title); // "中文標題"
console.log(data.content); // "換行\n內容" (含真實換行符)
// 若需在 HTML 屬性中傳遞
<div data-json='<?= htmlspecialchars(jsonEncodeSafe($arr), ENT_QUOTES) ?>'></div>
// JS 解析
var data = JSON.parse(document.querySelector('[data-json]').dataset.json);
</script>
<?php
function jsonEncodeBase64($array) {
return base64_encode(json_encode($array, JSON_UNESCAPED_UNICODE));
}
// 前端解碼
var data = JSON.parse(atob('<?= jsonEncodeBase64($arr) ?>'));
// 注意:atob() 不支持 Unicode,需 polyfill 或使用 base64.js
?>
缺點:增加體積 ~33%,舊瀏覽器需 polyfill,URL 傳輸需再次 encodeURIComponent。
<?php
// 1. 頁面聲明 UTF-8
header('Content-Type: application/json; charset=utf-8');
// 2. 數據庫讀取已為 UTF-8
// 3. 直接編碼,中文保持原樣
echo json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
// 輸出: {"title":"中文標題","content":"換行\n內容"}
?>
前提:數據源、PHP 文件、HTML 頁面、數據庫連接**全鏈路 UTF-8**。
| 方案 | 適用編碼 | 中文可讀 | 特殊字符安全 | 體積 | 推薦場景 |
|---|---|---|---|---|---|
| urlencode 中轉 | 任意 (GBK/UTF-8) | 是 | 是 | +0% | 存量 GBK 項目、混合編碼 |
| Base64 | 任意 | 是 | 極強 | +33% | POST 傳輸、複雜二進制數據 |
| UTF-8 + JSON_UNESCAPED_UNICODE | UTF-8 | 是 | 是 | +0% | **新項目標準**、現代化改造 |
json_encode。header('Content-Type: application/json; charset=gbk') 並配合方案一。json_decode 前確認編碼一致。htmlspecialchars($json, ENT_QUOTES)。