承接基礎用法,本文聚焦中文 Unicode 轉義控制、資料庫結果集高效轉換、複雜巢狀結構處理、自定義遞歸編碼等進階場景。
function fetchUsersAsJson(PDO $pdo, int $limit = 20): string {
$stmt = $pdo->prepare('SELECT id, username, email, created_at FROM users WHERE status = 1 ORDER BY id DESC LIMIT ?');
$stmt->execute([$limit]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 統一時間格式
array_walk($rows, function (&$row) {
$row['created_at'] = (new DateTime($row['created_at']))->format('c'); // ISO 8601
});
return json_encode([
'code' => 0,
'data' => ['list' => $rows],
'meta' => ['count' => count($rows)]
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
$response = [
'UserKeyGetResponse' => [
'RequestName' => $apiRequestName,
'api_key_value' => $apiKeyValue,
],
'error_response' => [
'code' => 'NO_ERROR',
'msg' => '獲取系統參數成功',
],
];
echo json_encode($response, JSON_UNESCAPED_UNICODE);
function jsonEncodeSafe(mixed $data, int $flags = 0, int $depth = 512): string|false {
// 預處理:遞歸走訪字串
array_walk_recursive($data, function (&$value, $key) {
if (is_string($value)) {
$value = trim($value);
// 例:手機號脫敏
if (stripos($key, 'phone') !== false || stripos($key, 'mobile') !== false) {
$value = preg_replace('/^(\d{3})\d{4}(\d{4})$/', '$1****$2', $value);
}
// 例:移除 BOM
$value = preg_replace('/^\xEF\xBB\xBF/', '', $value);
}
});
return json_encode($data, $flags, $depth);
}
| 現象 | 原因 | 解決 |
|---|---|---|
| 中文變 \uXXXX | 未加 JSON_UNESCAPED_UNICODE | PHP 5.4+ 加該旗標 |
| 返回 false / 空字串 | 資料含非 UTF-8 字元 | mb_check_encoding / iconv 清洗 |
| 大整數精度丟失 | JS Number 53 位有效數字 | 大整數以字串輸出,避免 JSON_NUMERIC_CHECK |
| 循環引用錯誤 | 物件屬性互相引用 | 實作 JsonSerializable 控制輸出 |
| 深度過大錯誤 | 巢狀超過 512 層 | 調整 $depth 參數或扁平化結構 |
json_encode 並流式輸出,避免記憶體飆升。igbinary / msgpack 二進制序列化 + 前端解碼庫。