【问题标题】:Create an object instance from cache trough the class in PHP通过 PHP 中的类从缓存中创建对象实例
【发布时间】:2011-08-06 05:14:07
【问题描述】:

给定一个包含一些非常昂贵的代码的类,我想在重新定义实例时避免运行该代码。

最好用一些伪代码来解释:

$foo = new Foo('bar');
print $foo->eat_cpu_and_database_resources(); #=> 3.14159
$foo->store_in_cache(); #Uses an existing Memcached and/or caching to store serialized.

#new thread, such as a new HTTP request. Could be days later. 
$bar = new Foo('bar');
print $foo->eat_cpu_and_database_resources(); #=> 3.14159

第二个 $bar 应该重新初始化之前创建的实例 $foo。在我的实际课堂中,我对名为 get_weighted_tags()eat_cpu_and_database_resources() 做了几件事:根据 $foo->tags 中的值计算加权标记云。 $foo->tags() 充满了昂贵的 $foo->add_tag() 电话。从现在开始,我想从缓存中检索准备和填充的实例。

我试图简单地从 __construct() 上的(序列化)缓存中获取并将检索到的实例分配给$this,这在 PHP 中是不允许的:

  function __construct ($id) {
    if ($cached = $this->cache_get($id)) {
      $this = $cached
    } 
    else {
      #initialize normally
    }
  }

这是正确的方法吗?或者我应该将每个实例都视为唯一,而是在 eat_cpu_and_database_resources() 方法中应用缓存,而不是缓存整个实例?

PHP 中是否有内置方式来恢复旧实例(在新线程中)?

【问题讨论】:

  • 嗯,你真的在​​使用缓存吗,比如 memcached 或 APC? #new thread 你的意思是新请求?或者您只想在一个请求期间拥有相同的实例? eat_cpu 方法是昂贵的还是实际的对象创建?你能把伪解码更具体吗?
  • 完成。我想强调缓存是一个已经可用的(Drupal)缓存系统:它将缓存在磁盘、memcached 或数据库(序列化)中,具体取决于设置等。 store_in_cache() 的来龙去脉并不重要,只是它将序列化并持久存储当前实例。
  • 我会尝试实现一些工厂方法,比如 Foo_Factory::create,它会首先检查你的缓存中的序列化对象。如果找到:$result = unserialize(...your source...) 否则创建一个新实例 ($result = new Foo(...constructor args...))。还有看看 __sleep/__wakeup,也许这些也会有帮助,php.net/manual/en/language.oop5.magic.php
  • Foo_Factory::create 是缺失的部分。谢谢。

标签: php oop caching


【解决方案1】:

根据 Foo 的大小,您可能希望将整个对象缓存在 Drupal 提供的缓存存储中。如果它太大了,看看将结果缓存到昂贵的方法调用是否有意义。

如果你想从 PHP 内部格式中反序列化一个对象,你必须使用相应的 unserialize 方法,并且可能需要添加 magic __wakeup method 来执行任何后期重新初始化:

__wakeup 的预期用途是重新建立在序列化期间可能丢失的任何数据库连接并执行其他重新初始化任务。

由于您必须首先获得序列化字符串,因此您可能需要添加一些工具来封装此逻辑,例如工厂或构建器模式或专用 FooCache。

我个人认为缓存方法调用是最好的选择,因为缓存整个对象是没有意义的,因为它实际上只是昂贵的方法调用。这也将节省您检查是否有序列化字符串开始或构建工厂的任何额外工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    • 1970-01-01
    • 2015-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多