添加Serializable接口后,unserialize()停止工作

问题描述 投票:2回答:1

我有一个使用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)
php oop serialization
1个回答
2
投票

问题是实现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。

© www.soinside.com 2019 - 2024. All rights reserved.