开发者

Create an object instance from cache trough the class in PHP

Given a class with some really expensive code, I want to avoid running that code when re-defining an instance.

Best explained with some pseudo-code:

$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

The second $bar should re-initialize the earlier created instance $foo. Inside my actual class, I do several things on eat_cpu_and_database_resources(), which is named get_weighted_tags(): calculate a weighted tagcloud from values in $foo->tags. $foo->tags() was filled with expensive $foo->add_tag() calls. I would like to retrieve the prepared and filled instance from now on, fr开发者_如何学Pythonom cache.

I have tried to simply fetch from (serialized) cache on __construct() and assign the retrieved instance to $this, which is not allowed in PHP:

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

Is this a proper way? Or should I treat every instance unique and instead apply caching in the eat_cpu_and_database_resources() method, instead of caching the entire instance?

Is there a built-in way in PHP to revive old instances (in a new thread)?


Depending on the size of Foo, you might want to cache the entire object in the cache store Drupal provides. If it's too big for that, see if it makes sense to just cache the result to the expensive method call(s).

If you want to unserialize an object from the PHP internal format, you have to use the corresponding unserialize method and might want to add the magic __wakeup method to do any post re-initializations:

The intended use of __wakeup is to reestablish any database connections that may have been lost during serialization and perform other reinitialization tasks.

Since you have to have the serialized string for that first, you might want to add some facilitiy to encapsulate this logic, like a Factory or Builder pattern or a dedicated FooCache.

Personally I find caching the method call the best option because there's no point in caching the whole object when it's really just the method call that's expensive. That will also save you any additional work checking whether there is a serialized string to start with or building a factory.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜