json_encode() 是 PHP 生成 JSON 的核心函數。本文涵蓋基本用法、數據庫查詢生成 JSON、中文 Unicode 轉義處理、自定義遞歸編碼函數、常見坑點與最佳實踐。
<?php
// 關聯陣列 → JSON 物件
echo json_encode(['a' => 'bbbb', 'c' => 'ddddd']);
// {"a":"bbbb","c":"ddddd"}
// 索引陣列 → JSON 陣列
echo json_encode(['apple', 'banana']);
// ["apple","banana"]
// 強制輸出物件(即使是索引陣列)
echo json_encode(['apple', 'banana'], JSON_FORCE_OBJECT);
// {"0":"apple","1":"banana"}
<?php
require 'Conn.php'; // 假設返回 $result 資源
// 單條記錄
$sql = "SELECT id, name FROM tbl_user WHERE id = 1";
$result = mysql_query($sql);
$row = mysql_fetch_assoc($result);
echo json_encode(['jsonObj' => $row]);
// {"jsonObj":{"id":"1","name":"lmw"}}
// 多條記錄
$sql = "SELECT id, name FROM tbl_user";
$result = mysql_query($sql);
$users = [];
while ($row = mysql_fetch_assoc($result)) {
$users[] = $row;
}
echo json_encode(['dataList' => $users]);
// {"dataList":[{"id":"1","name":"lmw"},{"id":"2","name":"xxj"}]}
mysql_free_result($result);
mysql_close();
$response = [
'UserKeyGetResponse' => [
'RequestName' => $api_request_name,
'api_key_value' => $api_key_value,
],
'error_response' => [
'code' => 'NO_ERROR',
'msg' => '獲取系統參數成功',
],
];
echo json_encode($response);
默認 json_encode 會將中文編碼為 \u4e2d\u6587,雖然標準 JSON 解析器均能正確解析,但調試困難、傳輸體積略大。
echo json_encode($data, JSON_UNESCAPED_UNICODE);
// 直接輸出中文字符,可讀性強
function arrayRecursive(&$array, $function, $apply_to_keys_also = false) {
static $recursive_counter = 0;
if (++$recursive_counter > 1000) {
die('Possible deep recursion attack');
}
foreach ($array as $key => $value) {
if (is_array($value)) {
arrayRecursive($array[$key], $function, $apply_to_keys_also);
} else {
$array[$key] = $function($value);
}
if ($apply_to_keys_also && is_string($key)) {
$new_key = $function($key);
if ($new_key != $key) {
$array[$new_key] = $array[$key];
unset($array[$key]);
}
}
}
$recursive_counter--;
}
// 使用:對所有值執行 urlencode,json_encode 後再 urldecode
arrayRecursive($data, 'urlencode', true);
$json = json_encode($data);
$json = urldecode($json);
echo $json; // 中文正常顯示
原理:urlencode 將中文轉為 %E4%B8%AD,json_encode 不轉義 %,最後 urldecode 還原。
| 常量 | 說明 |
|---|---|
JSON_HEX_TAG | < > 轉為 \u003C \u003E,防 XSS |
JSON_HEX_APOS | 單引號轉義 |
JSON_HEX_QUOT | 雙引號轉義 |
JSON_HEX_AMP | & 轉義 |
JSON_UNESCAPED_UNICODE | 不轉義 Unicode 字符(中文可讀) |
JSON_UNESCAPED_SLASHES | 不轉義 / |
JSON_NUMERIC_CHECK | 數字字串轉為數字類型 |
JSON_PRETTY_PRINT | 格式化輸出(調試用) |
JSON_PRESERVE_ZERO_FRACTION | 保留浮點數 .0 |
JSON_THROW_ON_ERROR | 編碼失敗拋異常 (PHP 7.3+) |
$options = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP;
echo json_encode($data, $options);
| 現象 | 原因 | 解決 |
|---|---|---|
返回 false | 編碼失敗(如資源類型、遞歸引用) | json_last_error_msg() 獲取具體錯誤 |
中文變 \uXXXX | 默認行為 | 加 JSON_UNESCAPED_UNICODE |
| 浮點數精度丟失 | JS 數字精度限制 | 大數字用字串傳輸,或 JSON_PRESERVE_ZERO_FRACTION |
| 資源類型編碼失敗 | 不支援 resource | 先轉為陣列/物件 |