根据the docs
当现在实现此接口的类的旧实例(在类实现接口之前已经序列化)被反序列化时,将调用__wakeup()而不是unserialize方法,这可能对迁移有用。 / p>
我认为这非常聪明和有用,并希望检查出来。不幸的是它对我不起作用,我想知道是否有一些我做错了或是否有错误。
测试代码:
//class Foo
class Foo implements \Serializable
{
public $a = 'lorem';
public function __wakeup()
{
fprintf(STDOUT, "in %s\n", __METHOD__);
}
public function serialize()
{
fprintf(STDOUT, "in %s\n", __METHOD__);
return serialize([
$this->a,
]);
}
public function unserialize($serialized)
{
fprintf(STDOUT, "in %s\n", __METHOD__);
list(
$this->a,
) = unserialize($serialized);
}
}
//$foo = new Foo();
//var_dump(serialize($foo));
//exit;
$serialised = 'O:3:"Foo":1:{s:1:"a";s:5:"lorem";}';
//$serialised = 'C:3:"Foo":22:{a:1:{i:0;s:5:"lorem";}}';
$foo = unserialize($serialised);
var_dump($foo);
它崩溃了:
Warning: Erroneous data format for unserializing 'Foo' in /in/SHaCP on line 39
Notice: unserialize(): Error at offset 13 of 34 bytes in /in/SHaCP on line 39
bool(false)
本质上,我在没有$foo
接口的情况下序列化\Serializable
对象。然后添加了接口并尝试unserialize()
在前一个表单中序列化的对象(请注意,以O
开头的序列化字符串没有接口,而以C
开头的序列化字符串是接口)。
我在这里做错了吗?或许我误解了文档?
答案 0 :(得分:0)
这是默认序列化与接口之间的主要区别 - 默认情况下,它序列化整个对象,但是通过接口的实现,您可以定义如何序列化已创建的对象'属性。
因此,由于内部实施,结果字符串将会有所不同 - 正如您在一种情况下可以看到它以" O"开头,而在另一种情况下它可以看到#& s" C"。因此,你必须再次保存它。