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

PHP JSON 編碼與解碼完整指南:json_encode、json_decode 進階用法與陷阱

     編輯:PHP 綜合知識

前言

自 PHP 5.2 起內建 json_encode() 與 json_decode(),成為前後端資料交換、API 回應、儲存結構化資料的標準工具。本文系統整理核心用法、常見陷阱與進階技巧。

json_encode() 核心用法

基本類型轉換

$arr = ['a' => 1, 'b' => 2, 'c' => 3];
echo json_encode($arr); // {"a":1,"b":2,"c":3}

$obj = new stdClass();
$obj->id = 100;
$obj->name = 'Test';
echo json_encode($obj); // {"id":100,"name":"Test"}

關鍵旗標

旗標用途範例效果
JSON_UNESCAPED_UNICODE不轉義 Unicode(中文可讀)"中文" 而非 "\u4e2d\u6587"
JSON_UNESCAPED_SLASHES不轉義 /"https://..." 而非 "https:\/\/..."
JSON_HEX_TAG轉義 < > 防 XSS內嵌 HTML script 安全
JSON_HEX_APOS轉義單引號\u0027
JSON_HEX_QUOT轉義雙引號\u0022
JSON_HEX_AMP轉義 &\u0026
JSON_NUMERIC_CHECK數值字串轉數值"123" → 123(謹慎使用)
JSON_PRETTY_PRINT美化縮排除錯/日誌易讀
JSON_FORCE_OBJECT索引陣列強制輸出物件["a","b"] → {"0":"a","1":"b"}
JSON_THROW_ON_ERROR錯誤拋出例外(PHP 7.3+)避免靜默失敗

推薦預設組合

$defaultFlags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_THROW_ON_ERROR;

$json = json_encode($data, $defaultFlags);

索引陣列 vs 關聯陣列

$indexed = ['apple', 'banana', 'cherry'];
echo json_encode($indexed); // ["apple","banana","cherry"] → JS 陣列

$assoc = ['a' => 'apple', 'b' => 'banana'];
echo json_encode($assoc);   // {"a":"apple","b":"banana"} → JS 物件

// 強制索引陣列輸出為物件
echo json_encode($indexed, JSON_FORCE_OBJECT); // {"0":"apple","1":"banana","2":"cherry"}

類別物件序列化

class User
{
    public string $name;
    private string $email;      // 私有屬性預設不輸出
    protected string $role;     // 受保護屬性預設不輸出
    public const TYPE = 'admin'; // 常數不輸出

    public function __construct(string $name, string $email, string $role)
    {
        $this->name = $name;
        $this->email = $email;
        $this->role = $role;
    }

    // 自訂序列化(PHP 8.1+ 可用 __serialize)
    public function jsonSerialize(): array
    {
        return [
            'name'  => $this->name,
            'email' => $this->email, // 選擇性暴露
            'role'  => $this->role,
        ];
    }
}

$user = new User('John', 'john@example.com', 'admin');
echo json_encode($user); // {"name":"John","email":"john@example.com","role":"admin"}

json_decode() 核心用法

預設回傳物件

$json = '{"a":1,"b":2}';
$obj = json_decode($json);
echo $obj->a; // 1
echo get_class($obj); // stdClass

強制回傳關聯陣列(推薦)

$arr = json_decode($json, true); // 第二參數 true
echo $arr['a']; // 1
echo gettype($arr); // array

深度限制與大整數處理

// 第 3 參數:最大深度(預設 512)
$deep = json_decode(str_repeat('{"a":', 1000) . '1' . str_repeat('}', 1000), true, 512); // null,超過深度

// 第 4 參數:選項旗標(PHP 7.3+)
$json = '{"id": 9007199254740993}'; // 超過 IEEE 754 安全整數
$obj = json_decode($json, false, 512, JSON_BIGINT_AS_STRING);
echo $obj->id; // "9007199254740993" 字串,避免精度遺失

常見錯誤與陷阱

錯誤 JSON原因正確寫法
{'a':1}單引號非標準{"a":1}
{a:1}鍵名未加雙引號{"a":1}
{"a":1,}尾隨逗號{"a":1}
undefined非 JSON 值null
NaN/Infinity非 JSON 數值null 或字串

錯誤處理最佳實踐

function safeJsonDecode(string $json, bool $assoc = true): array|object|null
{
    try {
        return json_decode($json, $assoc, 512, JSON_THROW_ON_ERROR | JSON_BIGINT_AS_STRING);
    } catch (JsonException $e) {
        error_log('JSON 解析失敗: ' . $e->getMessage() . ' | 輸入: ' . mb_substr($json, 0, 200));
        return null;
    }
}

效能提示

  • 大量資料序列化時,json_encode 比 serialize 快且跨語言相容。
  • 避免在迴圈中重複編碼相同資料;快取編碼結果。
  • 極大陣列(>100MB)考慮分塊處理或改用 JSON Stream(如 jsond 擴展)。

掌握 JSON 旗標與錯誤處理,能建構穩健、高效、跨平台相容的資料交換介面。

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