面向对象之对象序列化

对象序列化

  • serialize — 产生一个可存储的值。只保存所有变量和类的名字,但不会保存对象的方法
  • unserialize — 从已存储的表示中创建 PHP 的值
class Jack {

    public $name;
    public $age;
    public $like;

    public function __construct($user_name="null",$age="0",$like="") {
        $this->name = $user_name;
        $this->age = $age;
        $this->like = $like;
    }

    public function getInfo() {
        return "$this->name,今年$this->age,比较喜欢听$this->like";
    }
}

//实例化这个类
$jack = new Jack("聂哥",18,"喜欢许巍的歌");
//用serialize函数将这个实例转化为一个序列化的字符串
$str_jack = serialize($jack);
print $str_jack;//$ser_jack 已经序列化为字符串 
echo '<hr/>';

//我们在此注销这个类
unset($jack);

/* 
O:4:"Jack":3:{s:4:"name";s:4:"聂哥";s:3:"age";i:18;s:4:"like";s:12:"喜欢许巍的歌";}
-----------------------------------------------------------------------------------------
    在这里将字符串 $str_jack 从你存储的地方读出来如 session,cookie,数据库,php文件 
-----------------------------------------------------------------------------------------
*/

//我们在这里用 unserialize() 还原已经序列化的对象
$person = unserialize($str_jack);
//这个类此时无需实例化可以继续使用,而且属性和值都是保持在序列化之前的状态
$name = $person->getInfo();
# 聂哥,今年18,比较喜欢听喜欢许巍的歌

对象在session存储的时候,自动序列化

session_start();
$_SESSION = ['object'=>new Jack("聂哥",18,"喜欢许巍的歌")];
class Jack {

    public $name;
    public $age;
    public $like;

    public function __construct($user_name="null",$age="0",$like="") {
        $this->name = $user_name;
        $this->age = $age;
        $this->like = $like;
    }

    public function getInfo() {
        return "$this->name,今年$this->age,比较喜欢听$this->like";
    }
}

var_dump($_SESSION);

echo $_SESSION['object']->getInfo();

session文件里存储

object|O:4:"Jack":3:{s:4:"name";s:4:"聂哥";s:3:"age";i:18;s:4:"like";s:12:"喜欢许巍的歌";}

反序列化出现的错误

调用反序列化后的成员函数就出现了错误,__PHP_Incomplete_Class Object的问题。

问题其实很简单,就是反序列化处理的实例没有找到类的定义,处理的方法也很简单,让它找到类的定义就行了

和序列化有关的魔术方法

当序列化对象时,PHP 将在序列动作之前调用该对象的成员函数 __sleep()。这样就允许对象在被序列化之前做任何清除操作。类似的,当使用 unserialize() 恢复对象时, 将调用__wakeup()成员函数。

serialize()函数执行时,会先检查类中是否定义了__sleep()函数,如果存在,则首先调用__sleep()函数,如果不存在,就保留序列字符串中的所有属性。

unserialize()函数执行时,会先检查是否定义了__wakeup()函数。如果wakeup()存在,将执行__wakeup()函数,会使变量被重新赋值