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.
精彩评论