一.PHP序列化与反序列化
序列化:把对象转换为字节序列,永久存到磁盘中。在网络中传输对象也要进行序列化。
反序列化:从磁盘中读取字节序列将它们反序列化成对象读出来。
PHP中的serialize()和unserialize()两个函数:
1.serialize()
serizlize()就是将变量、对象、数组等数据类型转换成字符串方便进行网络传输和存储。
<?php
class Person{
//类的数据
public $age = 18;
public $name = 'lxy';
}
//创建一个对象
$usr = new Person();
//输出序列化后的数据
echo serialize($usr)
?>
打印其序列化结果:
O:6:"Person":2:{s:3:"age";i:18;s:4:"name";s:3:"lxy";}
“O”表示对象,“6”表示对象的类名长度,“Person”为对象名,“2”表示对象中有2个变量。
s:4:"name";s:3:"lxy"中,“s”表示变量类型,为string对象;s:4:"name"代表的是变量名长度和变量名,s:3:"lxy"代表的是变量的值,和值的长度。
注意:如果变量前是protected,则会在变量名前加上\x00*\x00
,
private则会在变量名前加上\x00类名\x00
。其中:\x00
表示空字符,但是还是占用一个字符位置(空格),如下例:
<?php
class test{
protected $a;
private $b;
function __construct(){
$this->a="name";
$this->b="sex";
}
}
$a = new test();
echo serialize($a);
?>
输出:
O:4:"test":2:{s:4:" * a";s:4:"name";s:7:" test b";s:3:"sex";}
序列化格式:
a - array 数组型
b - boolean 布尔型
d - double 浮点型
i - integer 整数型
o - common object 共同对象
r - objec reference 对象引用
s - non-escaped binary string 非转义的二进制字符串
S - escaped binary string 转义的二进制字符串
C - custom object 自定义对象
O - class 对象
N - null 空
R - pointer reference 指针引用
U - unicode string Unicode 编码的字符串
2.unserialize()
unserialize()将字符串进行转换成原来的数据。当存在反序列化函数及可利用魔术方法时,且unserialize()接受到的字符串对于用户是可控时,用户可针对使用的魔术方法来构造特定的语句,从而达到控制整个反序列化过程。
对上例进行反序列化:
<?php
class Person{
//类的数据
public $age = 18;
public $name = 'lxy';
//输出数据
public function printdata()
{
echo 'Person '.$this->name.' is '.$this->age.' years old.<br />';
}
}
//重建对象
$usr = unserialize('O:6:"Person":2:{s:3:"age";i:18;s:4:"name";s:3:"lxy";}');
//输出数据
$usr->printdata();
?>
输出结果:
Person lxy is 18 years old.
二.PHP中常用魔术方法及触发条件
PHP中把以两个下划线__
开头的方法称为魔术方法(Magic methods)
__construct() //类的构造函数,创建对象时触发
__destruct() //类的析构函数,对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //读取不可访问属性的值时,这里的不可访问包含私有属性或未定义
__set() //在给不可访问属性赋值时触发
__isset() //当对不可访问属性调用 isset() 或 empty() 时触发
__unset() //在不可访问的属性上使用unset()时触发
__invoke() //当尝试以调用函数的方式调用一个对象时触发
__sleep() //执行serialize()时,先会调用这个方法
__wakeup() //执行unserialize()时,先会调用这个方法
__toString() //当反序列化后的对象被输出在模板中的时候(转换成字符串的时候)自动调用