魔术方法__sleep和__wakeup、序列与反序列
来源:互联网 发布:mysql给表添加分区 编辑:程序博客网 时间:2024/05/22 00:09
串行化serialize可以把变量包括对象,转化成连续bytes数据. 你可以将串行化后的变量存在一个文件里或在网络上传输. 然后再反串行化还原为原来的数据. 你在反串行化类的对象之前定义的类,PHP可以成功地存储其对象的属性和方法. 有时你可能需要一个对象在反串行化后立即执行. 为了这样的目的,PHP会自动寻找__sleep和__wakeup方法.
当一个对象被串行化,PHP会调用__sleep方法(如果存在的话). 在反串行化一个对象后,PHP 会调用__wakeup方法. 这两个方法都不接受参数. __sleep方法必须返回一个数组,包含需要串行化的属性. PHP会抛弃其它属性的值. 如果没有__sleep方法,PHP将保存所有属性.
在程序执行前,serialize() 函数会首先检查是否存在一个魔术方法 __sleep.如果存在,__sleep()方法会先被调用, 然后才执行串行化(序列化)操作。这个功能可以用于清理对象,并返回一个包含对象中所有变量名称的数组。如果该方法不返回任何内容,则NULL被序列化,导致 一个E_NOTICE错误。与之相反,unserialize()会检查是否存在一个__wakeup方法。如果存在,则会先调用 __wakeup方法,预先准备对象数据。
__sleep方法常用于提交未提交的数据,或类似的操作。同时,如果你有一些很大的对象, 不需要保存,这个功能就很好用。__wakeup经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作。
<?phpclass Connection { protected $link; private $server, $username, $password, $db; public function __construct($server, $username, $password, $db) { $this->server = $server; $this->username = $username; $this->password = $password; $this->db = $db; $this->connect(); } private function connect() { $this->link = mysql_connect($this->server, $this->username, $this->password); mysql_select_db($this->db, $this->link); } public function __sleep() { return array('server', 'username', 'password', 'db'); } public function __wakeup() { $this->connect(); }}?>
下面例子显示了如何用__sleep和 __wakeup方法来串行化一个对象. Id属性是一个不打算保留在对象中的临时属性. __sleep方法保证在串行化的对象中不包含id属性. 当反串行化一个User对象,__wakeup方法建立id属性的新值. 这个例子被设计成自我保持. 在实际开发中,你可能发现包含资源(如图像或数据流)的对象需要这些方法。
<?phpclass user { public $name; public $id; function __construct() { // 给id成员赋一个uniq id $this->id = uniqid(); } function __sleep() { //此处不串行化id成员 return(array('name')); } function __wakeup() { $this->id = uniqid(); } }$u = new user();$u->name = "Leo"; $s = serialize($u); //serialize串行化对象u,此处不串行化id属性,id值被抛弃$u2 = unserialize($s); //unserialize反串行化,id值被重新赋值//对象u和u2有不同的id赋值print_r($u);print_r($u2);?>
例三:__wakeup方法的一个缺陷需要注意,如果你打算unserialize一个对象,你
<?php class A { public $b; public $name; } class B extends A { public $parent; public function __wakeup() { var_dump($parent->name); } } $a = new A(); $a->name = "foo"; $a->b = new B(); //我们期望这里输出:foo,但实际在后面的代码执行之后,实际输出NULL.$a->b->parent = $a; $s = serialize($a); $a = unserialize($s); ?>
原因:
所以,一定要小心你定义类中变量的执行顺序。
本文章转载自http://blog.sina.com.cn/s/blog_758ddcb90100yk05.html
- 魔术方法__sleep和__wakeup、序列与反序列
- PHP魔术方法之 __sleep() 和 __wakeup()
- php---魔术方法(__wakeup和__sleep)
- php---魔术方法(__wakeup和__sleep)
- 魔术方法__sleep和__wakeup的使用方法
- PHP魔术方法 __sleep和__wakeup()
- php---魔术方法(__wakeup和__sleep)
- PHP魔术方法 __sleep和__wakeup()
- 魔术方法:__sleep、__wakeup使用
- php 序列化 反序列化 __sleep __wakeup
- 序列化(serialize)和反序列化(unserialize)以及__sleep()函数和__wakeup()函数
- php 魔术方法 __sleep() __wakeup() __toString() __debuginfo()
- php面向对象(OOP)—序列化(串行化)与反序列化之serialize(),unserialize,__sleep(),__wakeup()
- 序列化,反序列化与相关魔术方法
- __sleep与__wakeup
- php __sleep() 和__wakeup()
- PHP魔术方法之序列化与反序列化技术
- php魔术方法(三)类的序列化和反序列化
- poj 3126(素数打表)
- leetcode217:Contains Duplicate
- 文件后缀名的显示
- ADS之can not openfile XX.o
- Struts中访问Servlet对象的方式(与Servlet API解耦的访问方式)
- 魔术方法__sleep和__wakeup、序列与反序列
- 矩阵分解——三角分解(二)
- android 采用windowmanager屏蔽HOME键
- Android自定义控件
- android button light 流程分析(一) — driver
- 【CSS疑难杂症】z-index 层级树
- spring IOC的好处与坏处
- MySQL—一个单引号引发的MYSQL性能损失
- hdu-1754 I Hate It(线段树求区间最大值)