PHP serialize() 與 json_encode() 都是將變量轉為字符串以便儲存或傳輸,但兩者在適用場景、效能、相容性上有本質差異。本文通過實例深度對比,助你做出正確選型。
$arr = [
0 => [
"gameName" => "德乙",
"homeName" => "比勒費爾德",
"guestName" => "不倫瑞克",
"endTime" => "2015-08-21"
],
1 => [
"gameName" => "英超",
"homeName" => "水晶宮",
"guestName" => "阿斯頓維拉",
"endTime" => "2015-08-22"
]
];
$serialize = serialize($arr);
echo $serialize;
// 輸出:
// a:2:{i:0;a:4:{s:8:"gameName";s:6:"德乙";s:8:"homeName";s:15:"比勒費爾德";s:9:"guestName";s:12:"不倫瑞克";s:7:"endTime";s:10:"2015-08-21";}i:1;a:4:{s:8:"gameName";s:6:"英超";s:8:"homeName";s:9:"水晶宮";s:9:"guestName";s:15:"阿斯頓維拉";s:7:"endTime";s:10:"2015-08-22";}}
| 標記 | 含義 | 範例 |
|---|---|---|
| a | Array (陣列) | a:2 = 2個元素的陣列 |
| i | Integer (整數) | i:0 = 整數 0 |
| s | String (字符串) | s:8:"gameName" = 長度8的字符串 |
| o | Object (物件) | O:8:"stdClass":3:{...} |
| b | Boolean | b:1 = true |
| d | Double (浮點數) | d:3.14 |
| N | NULL | N; |
| 維度 | serialize() | json_encode() |
|---|---|---|
| 可讀性 | 低(需解析器) | 高(人類可讀) |
| 跨語言 | 僅 PHP 可解析 | 所有主流語言支援 |
| 資料類型 | 完整保留(資源、物件、類別資訊) | 基礎類型(陣列、物件、標量、null) |
| 物件還原 | 自動呼叫 __wakeup(),保留類別 | 還原為 stdClass,失去原類別 |
| 輸出體積 | 較大(含類型標記、長度) | 較小(緊湊格式) |
| 編碼處理 | 原始二進制安全 | UTF-8 強制,中文轉 \uXXXX |
| 效能 | 序列化較快,反序列化較慢 | 編解碼速度均衡 |
| 安全性 | 反序列化有風險(物件注入) | 純數據,無執行風險 |
$data = [/* 大型測試數據 */];
// serialize
$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
$s = serialize($data);
$u = unserialize($s);
}
echo "serialize: " . (microtime(true) - $start) . "s\n";
// json
$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
$j = json_encode($data);
$d = json_decode($j, true);
}
echo "json: " . (microtime(true) - $start) . "s\n";
// 典型結果:serialize 序列化快 ~20%,json 反序列化快 ~30%,整體接近
需要跨語言/前端使用?
├─ 是 → JSON (唯一選擇)
└─ 否 → 需保留物件類別/資源類型?
├─ 是 → serialize() (配合 __sleep/__wakeup)
└─ 否 → 純陣列/標量數據?
├─ 儲存到資料庫/快取 → JSON (體積小、可讀、通用)
├─ Session/檔案儲存、PHP 內部傳遞 → 任皆可
└─ 高頻熱點路徑 → 基準測試決定
// 危險:不可信數據反序列化 $userData = unserialize($_COOKIE['data']); // 可能觸發 __wakeup()、__destruct() 鏈 // 安全:僅用 JSON $userData = json_decode($_COOKIE['data'], true);
原則:永遠不要對不可信輸入使用 unserialize(),這是 PHP 歷史上最嚴重的漏洞類別之一(CVE-2016-7124 等)。