我想在 PHP 中基于引用计数实现数据库缓存功能。例如,访问表 foo
中 ID 为 1 的记录的代码可能如下所示:
$fooRecord = $fooTable->getRecord(1);
第一次调用时,$fooTable
从数据库中获取适当的记录,将其存储在内部缓存中,然后返回它。对 getRecord(1)
的任何后续调用都将返回对内存中同一对象的另一个引用。 $fooRecord
在析构时向 $fooTable
发出信号,如果没有剩余引用,它会将任何更改存储回数据库并将其从缓存中删除。
问题在于 PHP 的内存管理抽象了有关引用计数的详细信息。我已经在 PECL 和 Google 上搜索了扩展程序来执行此操作,但没有找到任何结果。所以问题#1是:这样的扩展是否存在?
在另一种方法中,$fooTable 返回一个 super 偷偷摸摸的假对象。它通过转发__call()
、__set()
和__get()
来伪装成记录,其构造函数和析构函数提供相应的用于引用计数目的的钩子(Hook)。测试,效果很好,除了它破坏了类型提示。我所有期望 FooRecord 对象的方法现在都得到一个 Sneaky 对象,或者如果我想为我的每一个表创建一个 Sneaky 的空子类,那么可能是 FooSneaky,但我不想。另外,我担心它会让维护程序员(比如我自己)感到困惑。
问题#2:还有其他我错过的方法吗?
最佳答案
对于php5,只需使用记录类中的析构函数即可。
class Table {
/* [...] */
protected $record_cache = array();
public function getRecord($id) {
if(isset($this->record_cache[$id]) return $this->record_cache[$id];
$r = $db->getRecord($id);
if($r instanceof Record) {
$this->record_cache[$id] = $r;
}
return $r;
}
public function _unregister($id) {
unset($this->record_cache[$id]);
}
}
class Record {
/* [...] */
function __destruct() {
this->table->_unregister($this->id);
}
}
如果您不想在 Table 中为此使用公共(public)方法,您可能可以使用一些回调技巧或其他一些巧妙的技巧:)
关于php - PHP 中的引用计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/407980/