現代 Web 開發中,PHP 作為 API 後端頻繁返回 JSON。本文系統整理 json_encode 進階用法、數據庫查詢構建響應、中文 Unicode 處理、自定義遞歸編碼兼容舊版本、常見錯誤排查與在線工具推薦。
<?php
// 基礎
echo json_encode(['a' => 'bbbb', 'c' => 'ddddd']);
// {"a":"bbbb","c":"ddddd"}
// 關鍵選項組合(推薦生產環境默認)
$options = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP;
echo json_encode($data, $options);
<?php
$sql = "SELECT id, name FROM tbl_user WHERE id = 1";
$result = mysql_query($sql);
if ($result && $row = mysql_fetch_assoc($result)) {
echo json_encode(['jsonObj' => $row], $options);
}
// {"jsonObj":{"id":"1","name":"lmw"}}
<?php
$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], $options);
// {"dataList":[{"id":"1","name":"lmw"},{"id":"2","name":"xxj"}]}
$response = [
'UserKeyGetResponse' => [
'RequestName' => $api_request_name,
'api_key_value' => $api_key_value,
],
'error_response' => [
'code' => 'NO_ERROR',
'msg' => '獲取系統參數成功',
],
];
echo json_encode($response, $options);
默認輸出:{"msg":"\u83b7\u53d6\u7cfb\u7edf\u53c2\u6570\u6210\u529f"}
echo json_encode($data, JSON_UNESCAPED_UNICODE);
// {"msg":"獲取系統參數成功"}
function arrayRecursive(&$array, $function, $apply_to_keys_also = false) {
static $recursive_counter = 0;
if (++$recursive_counter > 1000) die('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 還原中文。
| 現象 | 原因 | 解決 |
|---|---|---|
返回 false | 編碼失敗 | json_last_error() / json_last_error_msg() |
| 中文變 \uXXXX | 默認行為 | 加 JSON_UNESCAPED_UNICODE |
| 資源類型編碼失敗 | 不支援 resource | 先轉陣列/物件 |
| 遞歸引用導致死循環 | 對象屬性互相引用 | 實現 JsonSerializable 控制輸出 |
| 浮點數精度問題 | JS Number 精度限制 | 大數用字串、或 JSON_PRESERVE_ZERO_FRACTION |
JSON_ERROR_NONE // 0 無錯誤
JSON_ERROR_DEPTH // 1 堆疊深度超限
JSON_ERROR_STATE_MISMATCH // 2 狀態不匹配(內部錯誤)
JSON_ERROR_CTRL_CHAR // 3 控制字符錯誤
JSON_ERROR_SYNTAX // 4 語法錯誤(解碼時)
JSON_ERROR_UTF8 // 5 UTF-8 編碼錯誤(輸入含無效序列)
JSON_ERROR_RECURSION // 6 遞歸引用
JSON_ERROR_INF_OR_NAN // 7 無限大/非數字
JSON_ERROR_UNSUPPORTED_TYPE // 8 不支援類型
JSON_UNESCAPED_UNICODE + 安全轉義選項{code, message, data}header('Content-Type: application/json; charset=utf-8')JsonException (PHP 7.3+ JSON_THROW_ON_ERROR)