為什麼 json_encode(['a','b']) 輸出 ["a","b"],而 json_encode([1=>'a',2=>'b']) 輸出 {"1":"a","2":"b"}?本文徹底解析 PHP 數組轉 JSON 時的「數組 vs 對象」判定邏輯。
json_encode 將 PHP 數組視為 JS 數組(列表) 的條件:
0,1,2...)。否則輸出為 JS 對象(字典)。
'a', 2 => 'b', 3 => 'c'];
echo json_encode($arr), "\n"; // {"1":"a","2":"b","3":"c"}
// 2. 連續從 0 開始 → 數組
$arr = [0 => 'a', 1 => 'b', 2 => 'c'];
echo json_encode($arr), "\n"; // ["a","b","c"]
// 3. 無顯式鍵(自動 0 開始) → 數組
$arr = ['a', 'b', 'c'];
echo json_encode($arr), "\n"; // ["a","b","c"]
// 4. 索引有間隙 → 對象
$arr = [0 => 'a', 1 => 'b', 5 => 'f'];
echo json_encode($arr), "\n"; // {"0":"a","1":"b","5":"f"}
// 5. 混合字符串鍵 → 對象
$arr = [0 => 'a', 1 => 'b', 'extra' => 'other'];
echo json_encode($arr), "\n"; // {"0":"a","1":"b","extra":"other"}
// 6. 實戰:數據庫 ID 作為鍵導致輸出對象
$users = [
10 => ['name' => '張三'],
20 => ['name' => '李四'],
];
echo json_encode($users); // {"10":{...},"20":{...}} ❌
// 修正:重置鍵或包裹層級
$list = array_values($users); // 強制重置為 0,1
echo json_encode(['list' => $list, 'count' => count($list)]);
// {"list":[{"name":"張三"},{"name":"李四"}],"count":2} ✅
PHP 5.4+ 支持 JSON_UNESCAPED_UNICODE 選項:
json_encode($arr, JSON_UNESCAPED_UNICODE); // 直接輸出中文,不轉 \uXXXX
不推薦常規使用:增加傳輸體積,前端現代框架均自動處理 Unicode,保持默認轉義更標準、更安全。
function apiResponse(array $list, array $meta = []): string {
$data = ['list' => array_values($list)]; // 強制列表格式
if ($meta) $data = array_merge($data, $meta);
return json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
| PHP 數組特徵 | JSON 輸出類型 | 典型場景 |
|---|---|---|
| 連續數字鍵 0,1,2... 無字符串鍵 | Array [...] | 列表、集合、隊列 |
| 數字鍵不從 0 開始 / 有間隙 / 混合字符串鍵 | Object {...} | 字典、映射、數據庫主鍵映射 |