如何使用Serializable接口来自定义PHP中类的序列化 |
||
关于PHP中的对象序列化这件事儿,之前我们在很早前的文章中已经提到过 __sleep() 和 __weakup() 这两个魔术方法 。今天我们介绍的则是另外一个可以控制序列化内容的方式,那就是使用 Serializable 接口 。它的使用和上述两个魔术方法很类似,但又稍有不同 。 Serializable接口class A implements Serializable { private $data; public function __construct(){ echo '__construct', PHP_EOL; $this->data = "This is Class A"; } public function serialize(){ echo 'serialize', PHP_EOL; return serialize($this->data); } public function unserialize($data){ echo 'unserialize', PHP_EOL; $this->data = unserialize($data); } public function __destruct(){ echo '__destruct', PHP_EOL; } public function __weakup(){ echo '__weakup', PHP_EOL; } public function __sleep(){ echo '__destruct', PHP_EOL; } } $a = new A(); $aSerialize = serialize($a); var_dump($aSerialize); // "C:1:"A":23:{s:15:"This is Class A";}" $a1 = unserialize($aSerialize); var_dump($a1); 这段代码就是使用 Serializable 接口来进行序列化处理的,注意一点哦,实现了 Serializable 接口的类中的 __sleep() 和 __weakup() 魔术方法就无效了哦,序列化的时候不会进入它们 。 Serializable 这个接口需要实现的是两个方法,serialize() 方法和 unserialize() 方法,是不是和那两个魔术方法完全一样 。当然,使用的方式也是一样的 。 在这里,我们多普及一点序列化的知识 。对象序列化只能序列化它们的属性,不能序列化他们方法 。如果当前能够找到对应的类模板,那么可以还原出这个类的方法来,如果没有定义过这个类的模板,那么还原出来的类是没有方法只有属性的 。我们通过这段代码中的序列化字符串来分析:
各种类型的数据进行序列化的结果
| 微信号终于可以修改了,但需要满足这些条件!你们满足吗? | 李佳琦“底价协议”事件是否涉嫌垄断? |
Windows XP系统正式发布20年了:居然还有近千万用户 | 饿了么点外卖折扣后比堂食贵?律师称属于价格欺诈 |
此外,如果我们手动将一个对象的 "O:" 转成 "C:" 会怎么样呢?
// 把O:替换成C: var_dump(unserialize(str_replace('O:', 'C:', $bSerialize))); // false
抱歉,无法还原了 。那么我们反过来,将上面 A 类也就是实现了 Serializable 接口的序列化字符串中的 "C:" 转成 "O:" 呢?
// Warning: Erroneous data format for unserializing 'A' var_dump(unserialize(str_replace('C:', 'O:', $aSerialize))); // false
嗯,会提示一个警告,然后同样也无法还原了 。这样看来,我们的反序列化还是非常智能的,有一点点的不同都无法进行还原操作 。
最后,我们来看看未定义类的情况下,直接反序列化一个对象 。
// 模拟一个未定义的D类 var_dump(unserialize("O:1:"D":2:{s:7:"win8.1怎么关闭触摸屏? windows8.1触摸屏关闭教程 华为手机信号,真的比其他家好吗? 爱奇艺VR公司被曝缓薪/欠薪,知情人:业务已基本停滞 什么是框架构图?根据场景我们可以有更美妙的构图
另外,我们可以发现,当序列化字符串中的模板不存在时,反序列化出来的类的类名是 __PHP_Incomplete_Class_Name 类,不像有类模板的反序列化成功直接就是正常的类名 。
其实从以上各种来看,个人感觉如果要保存数据或者传递数据的话,序列化并不是最好的选择 。毕竟包含了类型以及长度后将使得格式更为严格,而且反序列化回来的内容如果没有对应的类模板定义也并不是特别好用的,还不如直接使用 JSON 来得方便易读 。当然,具体情况具体分析,我们还是要结合场景来选择合适的使用方式 。
测试代码:
github.com/zhangyue050…
以上就是如何使用Serializable接口来自定义PHP中类的序列化的详细内容,更多关于自定义PHP中类的序列化的资料请关注脚本之家其它相关文章!