PHP 中 serialize() 與 json_encode() 同為數據序列化手段,但適用場景迥異。本文從定義、編碼長度、性能基準、對象方法保留、適用範圍五個維度深度對比,助你選型。
serialize() 保留類型、類名、屬性訪問權限、甚至私有屬性。<?php
class Foo {
public $int = 1;
public $bool = true;
public $array = [ [1], 2 => 'test', 'string' ];
}
$data = ['wwww' => 0, 'phppan' => 1, 'com' => 2];
$foo = new Foo();
// 序列化長度
echo '數組 serialize: ' . strlen(serialize($data)); // 52
echo '數組 json: ' . strlen(json_encode($data)); // 29
echo '對象 serialize: ' . strlen(serialize($foo)); // 111
echo '對象 json: ' . strlen(json_encode($foo)); // 63
結論:serialize() 輸出約為 JSON 的 1.7~2 倍。原因:
i/d/s/a/O 等),JSON 僅用簡單符號<?php $max = 10; $arr = array_fill(0, 1_000_000, rand(1, 9999)); $start = microtime(true); for ($i = 0; $i < $max; $i++) serialize($arr); echo 'serialize: ' . (microtime(true) - $start); // ~9.54 秒 $start = microtime(true); for ($i = 0; $i < $max; $i++) json_encode($arr); echo 'json_encode: ' . (microtime(true) - $start); // ~1.43 秒
結論:大數據量下 json_encode() 快約 6~7 倍(接近一個數量級)。
<?php
class Foo {
public function test($flag) { echo $flag, 'test function for Foo
'; }
}
$foo = new Foo();
// serialize/unserialize 保留類與方法
$foo->test(1);
$s = serialize($foo);
$o = unserialize($s);
$o->test(2); // 正常輸出
// json_encode/decode 丟失類信息,變為 stdClass
$foo->test(1);
$j = json_encode($foo);
$o = json_decode($j);
$o->test(2); // Fatal error: Call to undefined method stdClass::test()
關鍵差異:serialize() 保存類名與屬性結構,反序列化還原原類實例;json_encode() 僅保存屬性值,反序列化得到無方法的 stdClass。
| 場景 | 推薦 | 理由 |
|---|---|---|
| 對象持久化存儲(Session、緩存、數據庫 Blob) | serialize() | 需完整還原類實例、私有屬性、方法 |
| 純數據數組/對象存儲(無方法、無私有屬性) | json_encode() | 體積小、速度快、跨語言通用 |
| API 接口數據交換(AJAX、REST、微服務) | json_encode() | 標準化、前端原生解析、文檔友好 |
| 配置文件、日誌記錄 | json_encode() | 可讀性強、易手工編輯 |
| 包含資源類型、閉包、循環引用 | 均不支援 | 需自定義序列化方案 |
json_encode() 僅支援 UTF-8 編碼輸入,非 UTF-8 需先 iconv() 或 mb_convert_encoding()serialize() 二進制安全,不受編碼影響JsonSerializable 介面可自定義 JSON 序列化行為序列化 是 PHP 內部存儲對象狀態的專用格式,功能完整但體積大、速度慢、不可跨語言。JSON 是通用數據交換格式,輕量高效、生態通用,但無法保留對象行為。原則:存對象用 serialize,交換數據用 JSON。