PHP序列化对象(serialize)和json_encode对比

许亦
2023-12-01

PHP序列化(serialize)

·  数据类型的序列化

<?php
class CC {
    public $data;
    private $pass;

    public function __construct($data, $pass)
    {
        $this->data = $data;
        $this->pass = $pass;
    }
}

class DD extends CC
{
    public function __construct($data,$pass)
    {
        parent::__construct($data,$pass);
    }
}

trait AA 
{
    public $a;

    public function __construct()
    {
        $this->a=2;
    }

    public function say()
    {
        echo 'hello';
    }
}

trait BB 
{
    public function test()
    {
        echo 'world';
    }
}

class FF
{
    use AA,BB;
}

$number = 34;
$str = 'uusama';
$bool = true;
$null = NULL;
$arr = array('a' => 1, 'b' => 2);
$cc = new CC('uu', true);
$dd = new DD('uu', true);
$ff =new FF();

var_dump(serialize($number));
var_dump(serialize($str));
var_dump(serialize($bool));
var_dump(serialize($null));
var_dump(serialize($arr));
var_dump(serialize($cc));
var_dump(serialize($dd));
var_dump(serialize($ff));

输出结果为:

  1. int 类型 :i:34;
  2. string 类型 :s:6:"uusama";
  3. bool 类型 :b:1;
  4. null 类型 :N;
  5. array 类型 :a:2:{s:1:"a";i:1;s:1:"b";i:2;}
  6. 普通对象 :O:2:"CC":2:{s:4:"data";s:2:"uu";s:8:"\000CC\000pass";b:1;}
  7. 单继承对象 :O:2:"DD":2:{s:4:"data";s:2:"uu";s:8:"\000CC\000pass";b:1;}
  8. 多继承对象:O:2:"FF":1:{s:1:"a";i:2;}

 

__sleep()与__wakeup()

如果单纯的序列化对象,再反序列化。那么他只是实现了json_encode的功能,重复造轮子意义不大。序列化更强调的是状态的冻结、与状态的恢复。

<?php
class CC {

    private $content;
    private $test;

    public function __construct($content,$test=0)
    {
        $this->content = $content;
        $this->test=$test;
    }

    public function __sleep()
    {
        return [$this->content];
    }
}
$dd = new CC('uu');
var_dump(serialize($dd));

带__sleep()的情况序列化结果:

O:2:"CC":1:{s:2:"uu";N;}

注释__sleep()的结果:

O:2:"CC":2:{s:11:"\000CC\000content";s:2:"uu";s:8:"\000CC\000test";i:0;}

总结一下 sleep

如果sleep 有明确的返回数组 ,则系统按照sleep 函数的内容保存对应的数值和类型 。如果没有sleep函数,系统会默认保存所有的参数值及类型;

ps:  序列化不能实现函数和闭包序列化后再反序列化调用的操作;

 

__wakeup()

<?php
class CC {

    private $content;
    private $test;

    public function __construct($content,$test=0)
    {
        $this->content = $content;
        $this->test=$test;
    }

    public function __wakeup()
    {
        echo $this->test.PHP_EOL;
    }
}
$dd = new CC('uu');


var_dump($dd=serialize($dd));
var_dump(unserialize($dd));

结果如下:

class CC#1 (2) {
  private $content =>
  string(2) "uu"
  private $test =>
  int(0)
}

总结

__wakeup函数可以在反序列化的时候执行自己的逻辑。如果该函数不存在,反序列化只会对应对象的实例。

 

PHP  json_encode编码

<?php
class CC {
    public $data;
    private $pass;

    public function __construct($data, $pass)
    {
        $this->data = $data;
        $this->pass = $pass;
    }
}

class DD extends CC
{
    public function __construct($data,$pass)
    {
        parent::__construct($data,$pass);
    }
}

trait AA 
{
    public $a;

    public function __construct()
    {
        $this->a=2;
    }

    public function say()
    {
        echo 'hello';
    }
}

trait BB 
{
    public function test()
    {
        echo 'world';
    }
}

class FF
{
    use AA,BB;
}

$number = 34;
$str = 'uusama';
$bool = true;
$null = NULL;
$arr = array('a' => 1, 'b' => 2);
$cc = new CC('uu', true);
$dd = new DD('uu', true);
$ff =new FF();

var_dump(json_encode($number));
var_dump(json_encode($str));
var_dump(json_encode($bool));
var_dump(json_encode($null));
var_dump(json_encode($arr));
var_dump(json_encode($cc));
var_dump(json_encode($dd));
var_dump(json_encode($ff));

我们同样对一个基础的类实行json_encode ,结果如下

  1. int 类型 :34;
  2. string 类型 :"uusama";
  3. bool 类型 :"true"
  4. null 类型 :"null"
  5. array 类型 :{"a":1,"b":2}
  6. 普通对象 :{"data":"uu"}
  7. 单继承对象 :{"data":"uu"}
  8. 多继承对象:{"a":2}

现在我们在使用json_decode 来解码

  1. int 类型 :int(34)
  2. string 类型 :string(6) "uusama"
  3. bool 类型 :bool(true)
  4. null 类型 :NULL
  5. array 类型 :class stdClass#4 (2) {
    public $a =>
      int(1)
      public $b =>
      int(2)
    }
  6. 普通对象 :class stdClass#4 (1) {
      public $data =>
      string(2) "uu"
    }
  7. 单继承对象 :class stdClass#4 (1) {
      public $data =>
      string(2) "uu"
    }
  8. 多继承对象:class stdClass#4 (1) {
      public $a =>
      int(2)
    }

总结一下 json_encode()

json编码之后也能恢复原有的数据,也可以恢复部分数据的类型,区别在于恢复对象的时候,json_encode编码只会保存类的属性参数,不能保存类的完整信息,例如类的名称、类的私有变量、受保护的变量。

 

 

本章总结

json_encode 和类的序列化 相同点在于 保存数据的时候 包含 int、string、bool、array 时 具有相同的作用,可编译也可反编译恢复数据的值和类型、不同点在于,序列化除了能够保存数据之外 ,还能清晰的保存对象的信息,变量的可访问类别,和一系列的操作,而json_encode 只可以保存类的公共变量值和类型。所以 我们在选择保存对象的时候,可以根据对象的种类 选择合理的保存方式、另外在提一个注意点,json_encode的编码效率要高于序列化、怎么取舍看各位使用情况了。

转载于:https://my.oschina.net/u/4173863/blog/3081483

 类似资料: