【发布时间】: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是缺失的部分。谢谢。