6.自定义对象序列化
6.1.PHP 4 中自定义对象序列化
PHP 4 中提供了 __sleep 和 __wakeup 这两个方法来自定义对象的序列化。不过这两个函数并不改变对象序列化的格式,影响的仅仅是被序列化字段的个数。关于它们的介绍,在 PHP 手册中写的还算比较详细。这里就不再多做介绍了。
6.2.PHP 5 中自定义对象序列化
PHP 5 中增加了接口(interface)功能。PHP 5 本身提供了一个 Serializable 接口,如果用户在自己定义的类中实现了这个接口,那么在该类的对象序列化时,就会被按照用户实现的方式去进行序列化,并且序列化后的标示不再是 O,而改为 C。C 标示的格式如下:
C::""::{}
其中 表示类名 的长度, 表示自定义序列化数据 的长度,而自定义的序列化数据 是完全的用户自己定义的格式,与 PHP 序列化格式可以完全无关,这部分数据由用户自己实现的序列化和反序列化接口方法来管理。
Serializable 接口中定义了 2 个方法,serialize() 和 unserialize($data),这两个方法不会被直接调用,而是在调用 PHP 序列化函数时,被自动调用。其中 serialize 函数没有参数,它的返回值就是 的内容。而 unserialize($data) 有一个参数 $data,这个参数的值就是 的内容。这样大家应该就明白了,实际上接口中 serialize 方法就是让用户来自己序列化对象中的内容,序列化后的内容格式,PHP 并不关心,PHP 只负责把它充填到 中,等到反序列化时,PHP 只负责取出这部分内容,然后传给用户实现的 unserialize($data) 接口方法,让用户自己去反序列化这部分内容。
下面举个简单的例子,来说明 Serializable 接口的使用:
class MyClass implements Serializable
{
public $member;
function MyClass()
{
$this->member = 'member value';
}
public function serialize()
{
return wddx_serialize_value($this->member);
}
public function unserialize($data)
{
$this->member = wddx_deserialize($data);
}
}
$a = new MyClass();
echo serialize($a);
echo "\n";
print_r(unserialize(serialize($a)));
输出结果为(浏览器中的源代码):
C:7:"MyClass":90:{member value}
MyClass Object
(
[member] => member value
)
因此如果想用其它语言来实现 PHP 序列化中的 C 标示的话,也需要提供一种这样的机制,让用户自定义类时,能够自己在反序列化时处理 内容,否则,这些内容就无法被反序列化了。