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

JSON 兩大資料結構深度解析:物件與陣列的語意差異、巢狀結構與 PHP 編碼對應

     編輯:PHP 相關知識

JSON 核心資料結構:物件 {} 與陣列 [] 的語意邊界、序列化規則與跨語言對應

JSON (JavaScript Object Notation) 僅定義兩種資料結構:物件 (Object) 與陣列 (Array)。理解其語意差異、序列化規則與各語言對應關係,是前後端介接、API 設計、資料建模的基礎。本文系統性解析 JSON 雙重結構體系。

JSON 語法規範回顧

// 只有 4 種結構規則:
// 1. 並列資料用逗號分隔: "a": 1, "b": 2
// 2. 映射關係用冒號: "key": "value"
// 3. 陣列用方括號: [1, 2, 3]
// 4. 物件用大括號: {"key": "value"}

// 7 種資料型別:
// 字串、數值、布林、null、陣列、物件

核心語意差異:物件 vs 陣列

維度物件 {}陣列 []
語意無序鍵值集合 (Mapping)有序值序列 (Sequence)
鍵/索引字串鍵 (Key)整數索引 (Index: 0,1,2...)
順序性語意上無序 (實作常保留插入序)嚴格有序
存取方式obj.key / obj['key']arr[0], arr[1]
適用場景實體屬性、字典、設定列表、集合、時間序列
重複鍵不允許 (最後勝出)允許重複值

PHP 編碼對應規則 (json_encode)

// 索引陣列 (0 起始、連續) -> JSON 陣列
$indexed = [111, 'aaa', 'bbb'];
json_encode($indexed); // [111,"aaa","bbb"]

// 關聯陣列 (字串鍵/非連續/非 0 起始) -> JSON 物件
$assoc = ['a' => 'aaa', 'b' => 222];
json_encode($assoc); // {"a":"aaa","b":222}

// 混合/破壞連續性 -> JSON 物件
$broken = [0 => 'a', 2 => 'b']; // 缺少 1
json_encode($broken); // {"0":"a","2":"b"}

// 強制輸出
json_encode([1,2], JSON_FORCE_OBJECT); // {"0":1,"1":2}
json_encode((object)[1,2]);            // {"0":1,"1":2}

巢狀結構與複雜資料建模

$data = [
    'user' => [
        'id' => 123,
        'name' => 'John',
        'roles' => ['admin', 'editor'], // 陣列
        'profile' => [                  // 物件
            'avatar' => 'url',
            'bio' => 'Developer'
        ]
    ],
    'posts' => [                        // 陣列包含物件
        ['id' => 1, 'title' => 'Post 1'],
        ['id' => 2, 'title' => 'Post 2'],
    ]
];

// JSON 輸出:
// {
//   "user": {
//     "id": 123,
//     "name": "John",
//     "roles": ["admin", "editor"],
//     "profile": {"avatar": "url", "bio": "Developer"}
//   },
//   "posts": [
//     {"id": 1, "title": "Post 1"},
//     {"id": 2, "title": "Post 2"}
//   ]
// }

跨語言對應關係

語言JSON 物件 {}JSON 陣列 []
JavaScriptObject / MapArray
PHP關聯陣列 / stdClass索引陣列
Pythondictlist
JavaMap / JSONObjectList / JSONArray
Gomap[string]interface{} / structslice / []interface{}
C#Dictionary / JObjectList / JArray

PHP 解碼策略:json_decode() 參數控制

$json = '{"a":1,"b":[2,3],"c":{"d":4}}';

// 預設:物件轉為 stdClass
$obj = json_decode($json);
// $obj->a = 1
// $obj->b = stdClass (但實際是 array! PHP 特殊處理)
// $obj->c = stdClass

// true 參數:全部轉為關聯陣列
$arr = json_decode($json, true);
// $arr['a'] = 1
// $arr['b'] = [2, 3]
// $arr['c'] = ['d' => 4]

// 深度限制 (PHP 5.3+)
json_decode($json, false, 2); // 最大深度 2

// 大整數處理 (PHP 7.1+)
json_decode('{"id": 1234567890123456789}', false, 512, JSON_BIGINT_AS_STRING);
// 避免精度損失,回傳字串

API 設計決策指南

  1. 資源集合:永遠回傳陣列 [...],即使 0 或 1 筆資料
  2. 單一資源:回傳物件 {...}
  3. 字典/映射表:回傳物件 {"key": "value"}
  4. 錯誤回應:統一物件格式 {"code": 400, "message": "...", "details": {...}}
  5. 分頁回應:{"data": [...], "pagination": {"page": 1, "per_page": 20, "total": 100}}

常見設計錯誤

// ❌ 錯誤:單筆資源回傳陣列
GET /users/123
[{"id": 123, "name": "John"}] // 前端需寫 data[0].name

// ✅ 正確:回傳物件
{"id": 123, "name": "John"}

// ❌ 錯誤:集合回傳物件 (鍵為 ID)
{"123": {"name": "John"}, "456": {"name": "Jane"}}
// 無法保證順序、難以迭代、擴展性差

// ✅ 正確:集合回傳陣列
[{"id": 123, "name": "John"}, {"id": 456, "name": "Jane"}]

JSON Schema 定義範例

{
  "$schema": "https://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["id", "name"],
        "properties": {
          "id": {"type": "integer"},
          "name": {"type": "string"},
          "email": {"type": "string", "format": "email"}
        }
      }
    },
    "pagination": {
      "type": "object",
      "properties": {
        "page": {"type": "integer", "minimum": 1},
        "per_page": {"type": "integer", "minimum": 1},
        "total": {"type": "integer", "minimum": 0}
      }
    }
  }
}

JSON 看似簡單,但其物件/陣列語意邊界直接影響 API 易用性、前端程式碼複雜度與跨語言相容性。嚴格遵循「集合用陣列、實體用物件、映射用物件」原則,能構建直觀、穩健的資料介面。

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