我们已经序列化了存储在数据库中的类,我们正尝试使用新的psr 4类名进行反序列化。当我们运行反序列化功能时,无法正确创建该类。
新旧类是相同的,唯一真正改变的是名称从psr 0类名称到psr 4类不同。反序列化时,请确保使用class_alias将序列化代码中存储的旧类指向新类。反序列化时没有出现任何错误,但类属性未正确设置。
例如,我们正在使用序列化类Company_Shipping
。我们将该类的别名别名为Company\Shipping
,但是当我们转储对象时,我们会得到属性
private'_method'=>空
private'_method'(Company_Shipping)=>字符串'ground'(长度= 6)
我们应该得到
private'_method'=>字符串'ground'(长度= 6)
那么,有一种方法可以使用方括号中的旧类名称访问第二个私有属性?如果可以的话,我可以在__wake
方法中传输属性,但是我不知道如何访问它们。但是,如果有人知道如何解决此反序列化问题,那就太好了。
答案 0 :(得分:0)
问题是,所有私有属性都以完整的合格类名作为前缀-如果您使用别名,则无法解决。
您可以使用多个选项来解决此问题-但是大多数都无法使用现有数据。
选项(仅一个,可用于您现有的数据):更新序列化的字符串。如果您不存储复杂数据,则可以使用preg_replace_callback
和此正则表达式\bs:([0-9]+):"([^"]+)"
来完成。然后将是replace回调的任务,以更新长度(第一个匹配组)和类名+字段(第二个匹配组)。
选项:将所有private
字段设为public
或protected
。这样做将来不会对序列化造成任何问题。
选项:使类实现Serializable
接口。在这种情况下,您有两种方法(serialize
和unserialize
),它们进行序列化并可以与任何字符串一起使用。在这种情况下,您可以在serialize
中返回一个包含所有字段的序列化数组,并在unserialize
方法中,必须重新分配该值。
答案 1 :(得分:0)
这是一个很好的学习机会,了解private
为何过高。如果属性仅是protected
,则可以声明:
class Company_Shipping extends Company\Shipping {}
并且没有序列化也没有问题。
在这一点上,我想说,最好的选择是在应用程序中保留旧版Company_Shipping
对象代码的副本,编写一些代码以将Company_Shipping
转换为Company\Shipping
, [这又比需要困难,因为private
],然后将所有存储的对象显式重新编码为新格式,或者插入各种垫片以快速检测和转换它们。