用法如下:
$cache->set($key, $result, Configs::instance()->cacheDuration, new TagDependency([
'tags' => self::CACHE_TAG,
]));
在cache的set操作中,会将这个参数:
以$value = serialize([$value, $dependency]);的方式计算进cache的值中,然后$this->setValue($key, $value, $duration);保存下来。
最重要的是在这之前,会:$dependency->evaluateDependency($this);
这个操作会导致$dependency对象的改变。从而引起$key对应的值的变化。
public function evaluateDependency($cache)
{
if ($this->reusable) {
$hash = $this->generateReusableHash();
if (!array_key_exists($hash, self::$_reusableData)) {
self::$_reusableData[$hash] = $this->generateDependencyData($cache);
}
$this->data = self::$_reusableData[$hash];
} else {
$this->data = $this->generateDependencyData($cache);
}
}
通常$this-reusable为false,即默认值。
执行$this->data = $this->generateDependencyData($cache);也即data属性的改变,导致了该对象的改变。
我们此处用的是TagDependency,代码如下:
protected function generateDependencyData($cache)
{
$timestamps = $this->getTimestamps($cache, (array) $this->tags); $newKeys = [];
foreach ($timestamps as $key => $timestamp) {
if ($timestamp === false) {
$newKeys[] = $key;
}
}
if (!empty($newKeys)) {
$timestamps = array_merge($timestamps, static::touchKeys($cache, $newKeys));
} return $timestamps;
}
获取时间戳,第一次获取为所有$timestamp都是false。
主要看:
static::touchKeys($cache, $newKeys)
代码如下:
protected static function touchKeys($cache, $keys)
{
$items = [];
$time = microtime();
foreach ($keys as $key) {
$items[$key] = $time;
}
$cache->multiSet($items);
return $items;
}
给给予的key赋予一个毫秒时间戳,并批量设置cache。而:
protected function getTimestamps($cache, $tags)
{
if (empty($tags)) {
return [];
} $keys = [];
foreach ($tags as $tag) {
$keys[] = $cache->buildKey([__CLASS__, $tag]);
} return $cache->multiGet($keys);
}
用于获取对应key的值。
If a value is not cached or expired, the corresponding array value will be false.
这句话印证了前面说的,如果未设置会返回false。
总一句话,cache-set的第四个参数,生成了一组时间戳,赋值给了TagDependency的data,并且以$cache->buildKey([__CLASS__, $tag])所形成的key为key,时间戳为value存入cache。用这个时间戳来检测变化。
而TagDependency::invalidate(Configs::cache(), self::CACHE_TAG);用来重新设置时间,也就是刷新cache中以$cache->buildKey([__CLASS__, $tag])为key的值。