PHP中__sleep()与__wakeup()的用法

在 PHP 进行序列化时会用到__sleep()和__wakeup()这两个构造函数.

序列化即将一个变量或者一个对象转换成字节流的过程. 序列化有效的解决了对象的保存和传输问题, 例如:在使用 session 并使用了 session_register() 函数来注册对象, 这些对象会在每个 PHP 页面结束时被自动序列化, 并在接下来的每个页面中自动解序列化, 这样在每个 PHP 页面中都可以使用这些对象

01//整型
02$var = 23;
03echo serialize($var)."\n";   //i:23;
04  
05//浮点型
06$var = 1.23;
07echo serialize($var)."\n";   //d:1.229999999999999982236431605997495353221893310546875;
08  
09//字符串
10$var = "This is a string";
11echo serialize($var)."\n";   //s:16:"This is a string";
12  
13//布尔型
14$var = true;
15echo serialize($var)."\n";   //b:1;
16  
17//数组变量
18$var = array("abc","def", "xyz","123");
19echo serialize($var)."\n";   //a:4:{i:0;s:3:"abc";i:1;s:3:"def";i:2;s:3:"xyz";i:3;s:3:"123";}
20  
21$var = array("index1"=>"abc","index2"=>"def","index3"=>"xyz","index4"=>"123");
22echo serialize($var)."\n";   //a:4:{s:6:"index1";s:3:"abc";s:6:"index2";s:3:"def";s:6:"index3";s:3:"xyz";s:6:"index4";s:3:"123";}
23  
24//对象序列化
25class A{
26      public$a = "a string";
27      public$b = 123;
28      public$c = 123.12;
29}
30$obj = new A; 
31$str = serialize($obj);
32echo $str."\n";             //O:1:"A":3:{s:1:"a";s:8:"a string";s:1:"b";i:123;s:1:"c";d:123.1200000000000045474735088646411895751953125;} 
33$obj2 = unserialize($str);  //进行反序列化
34var_dump($obj2== $obj);    //bool(true)

程序运行时, serialize() 检查类中是否有 __sleep() ,如果有,则该函数将在任何序列化之前运行. 该函数必须返回一个需要进行序列化保存的成员属性数组,并且只序列化该函数返回的这些成员属性. 该函数有两个作用: 第一. 在序列化之前,关闭对象可能具有的任何数据库连接等. 第二. 指定对象中需要被序列化的成员属性,如果某个属性比较大而不需要储存下来,可以不把它写进__sleep()要返回的数组中,这样该属性就不会被序列化

__sleep() 方法常被用于提交未提交的数据, 或者类似的操作.

与 __sleep() 方法相反的情况, unserialize() 函数会检测是否存在 __wakeup() 函数, 如果存在会先调用 __wakeup(), 预先准备对象数据. 在用 unserialize()时需要注意的一个问题: 在一个PHP页面中要 unserialize() 一个对象,需要该页面包含该对象的类的定义.也就是,如果序列化了 page1.php 中类 A 的对象 $a, 要在 page2.php 中将其反序列化重建类 A 的对象 $a, 则 page2.php 中必须要出现类 A 的定义. 这可以这样实现,将类 A 的定义放在一个包含文件中,并在 page1.php 和 page2.php 都包含此文件. 所以强烈建议在所有的页面中都包括这些注册的对象的类的定义, 即使并不是在所有的页面中都用到了这些类. 如果没有这样做, 一个对象被反序列化了但却没有其类的定义,它将失去与之关联的类并成为 stdClass 的一个对象而完全没有任何可用的函数。

 
01//classa.inc:
02class
03{
04      var$one = 1;
05     
06      functionshow_one()
07      {
08          echo$this->one;
09      }
10}
11  
12//page1.php:
13include("classa.inc");
14  
15$a = new A;
16$s = serialize($a);
17$fp = fopen("store","w"); // 将 $s 存放在某处使 page2.php 能够找到
18fputs($fp,$s);
19fclose($fp);
20  
21//page2.php:
22include("classa.inc");     // 为了正常解序列化需要这一行
23  
24$s = implode("", @file("store"));
25$a = unserialize($s);
26  
27$a->show_one();// 现在可以用 $a 对象的 show_one() 函数了

__wakeup() 方法经常用在反序列化操作中, 例如重新建立数据库连接,或其他的初始化工作.

例子:

01class Connection {
02     protected$link;
03     private$server, $username,$password, $db;
04      
05     publicfunction __construct($server,$username, $password, $db)
06     {
07        $this->server =$server;
08        $this->username =$username;
09        $this->password =$password;
10        $this->db =$db;
11        $this->connect();
12     }
13      
14     privatefunction connect()
15     {
16        $this->link = mysql_connect($this->server,$this->username,$this->password);
17        mysql_select_db($this->db,$this->link);
18     }
19      
20     publicfunction __sleep()
21     {
22         returnarray('server','username', 'password', 'db');
23     }
24      
25     publicfunction __wakeup()
26     {
27        $this->connect();
28     }
29}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值