php 串行化 serialize() unserialize() session_register() __sleep() __wakeup()

zz from http://www.jxuan.com/archives/103

Code:
  1. 1. 串行化的基础认识:   是指将一个变量(包括对象)转换成字节流的过程。串行化有效的解决了对象的保存和传输的问题.例如,如果在用session并使用了 session_register() 来注册对象,这些对象会在每个 PHP 页面结束时被自动序列化,并在接下来的每个页面中自动解序列化,这样在每个PHP页面中都可以使用这些对象。PHP为我们提供了两个函数,用来进行串行化和反串行化的操作,这两个函数分别是:serialize()和unserialize()。serialize()可以处理除资源指针之外的所有类型, 该函数返回一个可以被存储在任何地点的字节流表达式的字符串。  
  2.   
  3. <?php  
  4. //整型  
  5. $var = 23;  
  6. echo serialize($var).”/n”;    //i:23;  
  7.   
  8. //浮点型  
  9. $var = 1.23;  
  10. echo serialize($var).”/n”;    //d:1.229999999999999982236431605997495353221893310546875;  
  11.   
  12. //字符串  
  13. $var = “This is a string”;  
  14. echo serialize($var).”/n”;    //s:16:”This is a string”;  
  15.   
  16. //布尔型  
  17. $var = true;  
  18. echo serialize($var).”/n”;    //b:1;  
  19.   
  20. //数组变量  
  21. $var = array(“abc”, “def”, “xyz”, “123″);  
  22. echo 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″;}  
  23.   
  24. $var = array(“index1″=>”abc”, “index2″=>”def”, “index3″=>”xyz”, “index4″=>”123″);  
  25. echo 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″;}  
  26.   
  27. //对象序列化  
  28. class A  
  29. {  
  30. public $a = “a string”;  
  31. public $b = 123;  
  32. public $c = 123.12;  
  33. }  
  34. $obj = new A;  
  35. $str = serialize($obj);  
  36. echo $str.”/n”;              //O:1:”A”:3:{s:1:”a”;s:8:”a string”;s:1:”b”;i:123;s:1:”c”;d:123.1200000000000045474735088646411895751953125;}  
  37. $obj2 = unserialize($str);   //进行反序列化  
  38. var_dump($obj2 == $obj);     //bool(true)  
  39. ?>  
  40.   
  41. 2. 在用 unserialize()时需要注意的一个问题: 在一个PHP页面中要 unserialize() 一个对象,需要该页面包含该对象的类的定义。也就是,如果序列化了 page1.php 中类 A 的对象 $a, 要在 page2.php 中将其反序列化重建类 A 的对象 $a,则 page2.php 中必须要出现类 A 的定义。这可以这样实现,将类 A 的定义放在一个包含文件中,并在 page1.php 和 page2.php 都包含此文件。 所以强烈建议在所有的页面中都包括这些注册的对象的类的定义,即使并不是在所有的页面中都用到了这些类。如果没有这样做,一个对象被反序列化了但却没有其类的定义,它将失去与之关联的类并成为 stdClass 的一个对象而完全没有任何可用的函数。(stdClass是一个空类,里面没有属性也没有方法  
  42.   
  43. var_dump(get_class_methods(stdClass));var_dump(get_class_vars(stdClass));)  
  44.   
  45. //classa.inc:  
  46. class A  
  47. {  
  48. var $one = 1;  
  49.   
  50. function show_one()  
  51. {  
  52. echo $this->one;  
  53. }  
  54. }  
  55.   
  56. //page1.php:  
  57. include(“classa.inc”);  
  58.   
  59. $a = new A;  
  60. $s = serialize($a);  
  61. $fp = fopen(“store”, “w”); // 将 $s 存放在某处使 page2.php 能够找到  
  62. fputs($fp$s);  
  63. fclose($fp);  
  64.   
  65. //page2.php:  
  66. include(“classa.inc”);      // 为了正常解序列化需要这一行  
  67.   
  68. $s = implode(“”, @file(“store”));  
  69. $a = unserialize($s);  
  70.   
  71. $a->show_one(); // 现在可以用 $a 对象的 show_one() 函数了  
  72.   
  73. ?>  
  74.   
  75. 如果以上的例子中 $a 通过运行 session_register(“a”) 成为了会话的一部分,$a会在该PHP 页面结束时被自动序列化,在其他PHP页面中会自动反序列化从而可以使用该对象,那么应该在所有的页面中包含 classa.inc 文件,而不只是 page1.php 和 page2.php。  
  76.   
  77. 3.__sleep() __wakeup()  
  78.   
  79. serialize() 检查类中是否有 __sleep() ,如果有,则该函数将在任何序列化之前运行。该函数必须返回一个需要进行序列化保存的成员属性数组,并且只序列化该函数返回的这些成员属性. 该函数有两个作用: 第一. 在序列化之前,关闭对象可能具有的任何数据库连接等. 第二. 指定对象中需要被序列化的成员属性,如果某个属性比较大而不需要储存下来,可以不把它写进__sleep要返回的数组中,这样该属性就不会被序列化  
  80.   
  81. 相反地,unserialize() 从字节流中创建了一个对象之后,马上检查是否具有__wakeup 的函数的存在。如果存在,__wakeup 立刻被调用。使用 __wakeup 的目的是重建在序列化中可能丢失的任何数据库连接以及处理其它重新初始化的任务。  
  82.   
  83. <?php  
  84. class User  
  85. {  
  86. public $name;  
  87. public $id;  
  88.   
  89. function __construct()  
  90. {  
  91. $this->id = uniqid();          //give user a unique ID 赋予一个不同的ID  
  92. }  
  93.   
  94. function __sleep()  
  95. {  
  96. return(array(“name”));        //do not serialize this->id 不串行化id  
  97. }  
  98.   
  99. function __wakeup()  
  100. {  
  101. $this->id = uniqid();         //give user a unique ID  
  102. }  
  103. }  
  104.   
  105. $u = new User;  
  106. $u->name = “HAHA”;  
  107.   
  108. $s = serialize($u);                   //serialize it 串行化 注意不串行化id属性,id的值被抛弃  
  109.   
  110. $u2 = unserialize($s);                //unserialize it 反串行化 id被重新赋值  
  111. //$u and $u2 have different IDs $u和$u2有不同的ID  
  112. var_dump($u);  
  113. var_dump($u2);  
  114. ?>  
  115.   
  116. ———- PHP debug ———-  
  117. object(User)#1 (2) {  
  118. ["name"]=>  
  119. string(4) “HAHA”  
  120. ["id"]=>  
  121. string(13) “47fa045529f69″  
  122. }  
  123. object(User)#2 (2) {  
  124. ["name"]=>  
  125. string(4) “HAHA”  
  126. ["id"]=>  
  127. string(13) “47fa04552a49a”  
  128.   
  129. }  
  130. 输出完成 (耗时: 0 秒) – 正常终止  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值