首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP JSON 編解碼最佳實務:json_encode/json_decode 版本相容與效能優化

     編輯:PHP 相關知識

前言

JSON 是現代 Web API 事實標準。PHP 5.2+ 內建 json_encode/json_decode,但舊專案可能運行在 PHP 5.1 或需支援舊版本。本文涵蓋版本相容策略、常用選項旗標、錯誤處理、效能優化與安全防護。

版本相容策略

<?php
/**
 * 統一 JSON 編碼介面(自動偵測內建函式或回退 polyfill)
 */
function json_encode_compat(mixed $value, int $flags = 0, int $depth = 512): string|false {
    if (function_exists('json_encode')) {
        return json_encode($value, $flags, $depth);
    }
    // 回退:載入 polyfill(如 Services_JSON)
    require_once __DIR__ . '/vendor/Services_JSON.php';
    $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
    return $json->encode($value);
}

/**
 * 統一 JSON 解碼介面
 */
function json_decode_compat(string $json, bool $assoc = false, int $depth = 512, int $flags = 0): mixed {
    if (function_exists('json_decode')) {
        return json_decode($json, $assoc, $depth, $flags);
    }
    require_once __DIR__ . '/vendor/Services_JSON.php';
    $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
    return $json->decode($json, $assoc);
}

常用旗標速查表 (PHP 5.3+)

旗標版本用途推薦場景
JSON_HEX_TAG5.3< > 轉 \u003C \u003E嵌入 HTML/JS 防 XSS
JSON_HEX_AMP5.3& 轉 \u0026同上
JSON_HEX_APOS5.3' 轉 \u0027同上
JSON_HEX_QUOT5.3" 轉 \u0022同上
JSON_UNESCAPED_UNICODE5.4不轉義中文/Unicode,直接輸出中文 API 必開,減少體積、提升可讀性
JSON_UNESCAPED_SLASHES5.4不轉義 /URL、路徑輸出
JSON_NUMERIC_CHECK5.3數字字串轉數值型別謹慎使用,可能改變語意(如手機號、ID)
JSON_PRETTY_PRINT5.4格式化縮排輸出除錯、日誌、配置檔
JSON_PRESERVE_ZERO_FRACTION5.6保留浮點數 .0精確數值傳輸
JSON_THROW_ON_ERROR7.3錯誤拋出 JsonException現代專案必開,避免靜默失敗
JSON_INVALID_UTF8_IGNORE7.2忽略無效 UTF-8 字元髒資料清洗
JSON_INVALID_UTF8_SUBSTITUTE7.2無效 UTF-8 替換為 U+FFFD同上

推薦預設組合

// API 回應標準旗標(PHP 7.3+)
$flags = JSON_UNESCAPED_UNICODE 
       | JSON_UNESCAPED_SLASHES 
       | JSON_THROW_ON_ERROR;

// 除錯/日誌旗標
$debugFlags = $flags | JSON_PRETTY_PRINT;

// 使用
try {
    $json = json_encode($data, $flags);
    echo $json;
} catch (JsonException $e) {
    error_log('JSON 編碼失敗: ' . $e->getMessage());
    http_response_code(500);
    echo '{"error":"Internal Server Error"}';
}

錯誤處理最佳實務

// PHP 7.3+ 推薦
json_decode($json, true, 512, JSON_THROW_ON_ERROR);

// PHP 7.2 及以下:手動檢查
$data = json_decode($json, true);
if (json_last_error() !== JSON_ERROR_NONE) {
    throw new RuntimeException('JSON 解析錯誤: ' . json_last_error_msg());
}

// 常見錯誤代碼
// 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 不支援型別(如 resource)

效能優化技巧

  1. 避免重複編碼:快取 json_encode 結果(Redis、APCu、檔案快取)。
  2. 大陣列分批處理:超大資料集用 Generator 分塊 json_encode,再手動拼接 [,](罕見需求)。
  3. 移除不必要資料:序列化前過濾 null、內部欄位、遞迴參考。
  4. 使用 igbinary/msgpack:內部儲存/快取改用二進位序列化,速度快 2-5 倍、體積小 30-50%。
  5. OpCache 預載入:PHP 7.4+ opcache.preload 載入常用類別,減少編譯開銷。

安全防護

  • 輸入長度限制:json_decode(substr($input, 0, 1_000_000)) 防止巨大 JSON 耗盡記憶體。
  • 深度限制:預設 512 足夠,避免惡意巢狀結構導致堆疊溢位。
  • 型別檢查:解碼後嚴格驗證結構(is_array, isset, filter_var),不要信任客戶端資料。
  • 避免 JSONP:現代瀏覽器支援 CORS,JSONP 易遭 XSS 攻擊。

常見陷阱

陷阱現象解法
中文變 \uXXXX預設 escape Unicode加 JSON_UNESCAPED_UNICODE
數字字串變數值JSON_NUMERIC_CHECK移除該旗標,手動轉型
資源型別失敗resource 無法序列化預先轉陣列/物件
循環參考遞迴導致錯誤實作 JsonSerializable 或斷開循環
浮點精度0.1+0.2=0.30000000000000004JSON_PRESERVE_ZERO_FRACTION 或字串化

總結

掌握 json_encode/decode 的旗標組合、錯誤處理、版本相容、安全限制,是 PHP 開發者的基本功。現代專案(PHP 7.3+)請務必開啟 JSON_THROW_ON_ERROR + JSON_UNESCAPED_UNICODE + JSON_UNESCAPED_SLASHES,並建立統一封裝函式,讓全專案 JSON 行為一致、可測、可維護。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved