在PHP中,如何反序列化为当前对象?

时间:2011-03-30 20:08:52

标签: php serialization object constructor

这可能是一个菜鸟问题,所以请善待。

我正在尝试在昂贵的“活动”对象上实现缓存。在构造函数中,我首先检查缓存以查看此Activity实例是否已存在。如果没有,我会执行所有查询来构建对象,将其序列化并将其保存到缓存中。下次进入时,我检查缓存,我的对象就在那里,所以我将它反序列化。现在是我的问题,如何将该对象放入$this当前对象?我不能只说"$this = unserialize($row[0]);"失败并显示错误消息“无法在ActivityClass.php中重新分配$this”。我错过了什么?

非常感谢! 麦克

3 个答案:

答案 0 :(得分:3)

如果您不希望您的构造离开课程,您可以创建工厂方法:

class Activity
{
    public static function Create(/* your params */)
    {
        // construct cache and key, whatever
        $obj = unserialize($cache->get($key));

        if ($obj) return $obj;

        return new Activity(/* params */);
    }

    // rest of your stuff
}

答案 1 :(得分:1)

您必须仅序列化对象的内部状态,即其参数(也称为“成员变量”)。事实上,在这种情况下,serialize()并不是你想要做的;相反,您希望将ActivityClass的数据存储到缓存中,而不是整个对象的序列化。但是,这很棘手,因为稍后添加新参数时,您需要记住将它们存储在缓存中。

或者,您可以为ActivityClass实现单例或工厂模式。既然你说你在构造函数中从缓存中提取类,我认为在任何给定的时间内只有一个这个类的实例存在?在这种情况下,您应该通过执行以下操作使您的类成为单身:

  1. __construct()方法设为私有或受保护。
  2. 创建一个公共静态方法(我倾向于调用此getInstance()),它将检查对象的缓存,或者实例化一个新的,然后缓存它。
  3. 现在不是直接实例化一个新的ActivityClass对象,而是编写$foo = ActivityClass::getInstance();,它会为您提供一个新对象或反序列化并返回您的缓存对象。

答案 2 :(得分:0)

正如您所注意到的,您不能只是覆盖整个当前对象。


相反,可能的方法是将您正在序列化/反序列化的数据存储到对象的属性中。

这样,您不会序列化整个对象,只会序列化其中一个属性 - 并且在反序列化时只会覆盖该单个属性。

通常,您不会序列化与数据库的连接,这可能是您对象的另一个属性。


另一种可能性是没有你的对象处理它自己的(de-)序列化

相反,你应该:

  • 使用外部类来实现对象
  • 由外部班负责:
    • 从缓存加载数据并将其推送到您的对象中
    • 或者调用类的正确方法,从数据库加载数据 - 然后将该对象保存到缓存中。