PHP中serialize和json序列化與反序列化的區別

(本文轉載自 https://blog.tanteng.me/2015/11/serialize-json-diff/)web

在PHP中,serialize和json兩種方式對一個對象或數組進行序列化或反序列化有什麼區別呢?數據庫

假設一個對象和一個數組:json

PHP數組

1ide

2函數

3this

4編碼

$web = new stdClass;spa

$web->site = 'tantengvip';code

$web->owner = 'tuntun';

$web->age = 5;

PHP

1

2

3

4

$web = array();

$web['site'] = 'tantengvip';

$web['owner'] = 'tuntun';

$web['age'] = 5;

對它們分別用serialize函數和unserialize函數進行序列化和反序列化,看看打印結果分別是什麼,以下:

使用serialize方式:

PHP

1

2

3

4

var_dump(serialize($web));

var_dump(unserialize(serialize($web)));

var_dump(json_encode($web));

var_dump(json_decode(json_encode($web)));

結果:

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

string 'O:8:"stdClass":3:{s:4:"site";s:10:"tantengvip";s:5:"owner";s:6:"tuntun";s:3:"age";i:5;}' (length=87)

 

object(stdClass)[127]

  public 'site' => string 'tantengvip' (length=10)

  public 'owner' => string 'tuntun' (length=6)

  public 'age' => int 5

 

string '{"site":"tantengvip","owner":"tuntun","age":5}' (length=46)

 

object(stdClass)[127]

  public 'site' => string 'tantengvip' (length=10)

  public 'owner' => string 'tuntun' (length=6)

  public 'age' => int 5

使用json方式:

PHP

1

2

3

4

var_dump(serialize($web));

var_dump(unserialize(serialize($web)));

var_dump(json_encode($web));

var_dump(json_decode(json_encode($web),true));

結果

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

string 'a:3:{s:4:"site";s:10:"tantengvip";s:5:"owner";s:6:"tuntun";s:3:"age";i:5;}' (length=74)

 

array (size=3)

  'site' => string 'tantengvip' (length=10)

  'owner' => string 'tuntun' (length=6)

  'age' => int 5

 

string '{"site":"tantengvip","owner":"tuntun","age":5}' (length=46)

 

array (size=3)

  'site' => string 'tantengvip' (length=10)

  'owner' => string 'tuntun' (length=6)

  'age' => int 5

咱們發現,對於前面定義的這樣一個對象或數組,用serialize和json進行序列化,反序列化回來的結果和原來是同樣的,並無什麼區別,除了序列化的格式不一樣而已。

那麼它們到底有何區別?如下文字總結很好,就不本身加以說明了,能夠寫代碼驗證。(連接

使用json序列化和反序列化

優點:

  • 變量序列化後依然可讀

  • 能夠給其餘系統使用,由於JSON格式是標準的

劣勢:

  • 只對UFT-8的數據有效,其餘編碼可能不能很好工做

  • 只對stdClass類的示例有效

使用serialize方式序列化和反序列化

優點:

  • 容許非UTF-8的變量

  • 支持除了stdClass 示例外的其餘實例

劣勢:

  • 編碼後的文本對人來講是不可讀的

  • 沒法被其餘語言的系統引用

好,寫個代碼看看:

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

class Test

{

    private $pri = 'pri';

    public $class = 'Test';

    public function __construct()

    {

        $this->class = 'Test construct';

        $this->pri = 'pri construct';

    }

}

 

$test = new Test();

 

var_dump(serialize($test));

var_dump(unserialize(serialize($test)));

 

var_dump(json_encode($test));

var_dump(json_decode(json_encode($test)));

結果:

PHP

1

2

3

4

5

6

7

8

9

10

string 'O:4:"Test":2:{s:9:"Testpri";s:13:"pri construct";s:5:"class";s:14:"Test construct";}' (length=86)

 

object(Test)[127]

  private 'pri' => string 'pri construct' (length=13)

  public 'class' => string 'Test construct' (length=14)

 

string '{"class":"Test construct"}' (length=26)

 

object(stdClass)[127]

  public 'class' => string 'Test construct' (length=14)

咱們發現,json序列化和反序列化丟失了類中的私有成員變量,而serialize序列化和反序列化只要是類的變量均可以,可是類的成員方法都沒法進行序列化和反序列化。

在通常狀況,仍是使用json比較好,由於json是跨平臺的通用格式,除了json,用xml也比較好。那在何時使用serialize方式呢?

在對一個類進行serialize反序列化的時候會默認調用魔術方法__wakeUp(),這樣就使得對象可以從新創建起序列化時未能保留的各類狀態。例如:數據庫鏈接等。那就是另一個問題了,這裏不作深究了。

相關文章
相關標籤/搜索