【问题标题】:In PHP, how can I unserialize into the current object?在 PHP 中,如何反序列化为当前对象?
【发布时间】:2011-07-26 09:22:24
【问题描述】:

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

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

非常感谢! 迈克

【问题讨论】:

  • 所以基本上你想将当前对象与你正在缓存的对象“合并”?
  • 你不能那样做。通常,您会在缓存中检查一个对象是否可以在 自己创建一个对象之前在与目标对象本身不同的上下文中被拉出。当然,您可以只定义一个方法来转移昂贵的属性。

标签: php serialization object constructor


【解决方案1】:

如果你不希望你的构造离开类,你可以创建一个工厂方法:

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
}

【讨论】:

    【解决方案2】:

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

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

    1. __construct() 方法设为私有或受保护。
    2. 创建一个公共静态方法(我倾向于称之为getInstance()),它将检查您的缓存中的对象,或者实例化一个新的对象然后缓存它。

    现在不是直接实例化一个新的 ActivityClass 对象,而是编写 $foo = ActivityClass::getInstance();,它会为您提供一个新对象或反序列化并返回您缓存的对象。

    【讨论】:

      【解决方案3】:

      正如您所注意到的,您不能将当前对象作为一个整体覆盖。


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

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

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


      另一种可能性是不让您的对象处理自己的(反)序列化

      相反,您应该:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-07
        • 1970-01-01
        • 1970-01-01
        • 2017-03-16
        • 2011-05-21
        • 1970-01-01
        相关资源
        最近更新 更多