我有一个使用serialize()
存储在MySql中的对象。
现在我通过实现Serializable
接口来更新类定义,并且我不能反序列化对象,因为:
Erroneous data format for unserializing 'ClassName'
这个类的调试方法unserialize()
没有用 - 它甚至都没有被调用。
举个例子,假设我有旧的(A)和新的(B)类声明:
<?php
class A {
public $hello = "world";
}
class B implements Serializable {
public $hello = "world";
public function serialize() {}
public function unserialize($serialized) { throw new Exception("test"); }
}
现在,当我尝试反序列化数据时:
$data1 = 'O:1:"A":1:{s:5:"hello";s:5:"world";}';
$data2 = 'O:1:"B":1:{s:5:"hello";s:5:"world";}';
var_dump(unserialize($data1));
var_dump(unserialize($data2));
我明白了
object(A)#2 (1) {
["hello"]=>
string(5) "world"
}
<br />
<b>Warning</b>: Erroneous data format for unserializing 'B' in <b>[...][...]</b> on line <b>20</b><br />
<br />
<b>Notice</b>: unserialize(): Error at offset 11 of 36 bytes in <b>[...][...]</b> on line <b>20</b><br />
bool(false)
问题是实现Serializable
的类和不实现接口的类使用不同的序列化格式。
不实现接口的类将使用“O表示法”:
O:1:"A":1:{s:5:"hello";s:5:"world";}
而实施qazxsw poi的类将使用“C表示法”。您的Serializable
类,序列化将如下所示:
B
反序列化不会起作用,因为你试图反序列化为“错误”的定义。
这种变化发生在5.6,C:1:"B":12:{s:5:"world";}
,因为旧行为的安全含义。
据我所知,你试图做的只能从PHP 5.3到5.5。在调用was reported as a bug and the response was wontfix之前调用了用于实现Serializable
的类的文档qzxswpoi方法,但这是5.6中删除的内容的一部分。
您需要使用一些解决方法来反序列化该数据,从长远来看,我会将序列化数据迁移到更安全,更可移植的格式,如JSON。