缓存元素

3.4 版本
维护中的版本

Cache items(缓存元素)是以键值对方式存储在缓存中的信息单元。Cache组件中,它们通过 CacheItem 类来呈现。

缓存元素的键和值 

缓存元素的 key(键)是个UTF-8编码的字符串,作为其识别符,因此它对于每一个缓存池来说必须唯一。你可以自由选择键, 但它们应当只包含字母 (A-Z, a-z)、数字 (0-9) 和下划线 _ 以及 . 逗点。 其他常见符号 (比如 {, }, (, ), /, \@) 被PSR-6标准保留了,留待后用。

创建缓存元素 

缓存元素由缓存池的 getItem($key) 方法创建。其参数是元素的键:

1
2
3
// $cache pool object was created before
// $cache pool 对象是之前创建的
$numProducts = $cache->getItem('stats.num_products');

然后,使用 set() 来设置存储在缓存元素中的数据:

1
2
3
4
5
6
7
8
9
10
// storing a simple integer / 存入整型
$numProducts->set(4711);
$cache->save($numProducts);
 
// storing an array / 存入一个数组
$numProducts->set(array(
    'category1' => 4711,
    'category2' => 2387,
));
$cache->save($numProducts);

任何给定的缓存元素的键和值,都可以通过相应的getter 方法来获取:

1
2
3
4
$cacheItem = $cache->getItem('exchange_rate');
// ...
$key = $cacheItem->getKey();
$value = $cacheItem->get();

缓存元素过期 

默认时,缓存元素被永久存储。实践中,这个“永久存储”因取决于所使用的缓存类型而会有很大不同,缓存池 Cache Pools 一文中有详细解释。

但是,在一些程序中,在有限周期内使用缓存元素也很常见。思考这样的例子,一个程序对最新新闻只缓存一分钟。这种情况下,使用 expiresAfter() 方法来设置元素被缓存的秒数:

1
2
3
4
5
6
$latestNews = $cache->getItem('latest_news');
$latestNews->expiresAfter(60);  // 60 seconds = 1 minute / 60秒 = 1分
 
// this method also accepts \DateInterval instances
// 本方法也能接收 \DateInterval instances
$latestNews->expiresAfter(DateInterval::createFromDateString('1 hour'));

缓存元素定义了另一个相关方法叫 expiresAt(),用来在元素过期时设置确切的日期和时间:

1
2
$mostPopularNews = $cache->getItem('popular_news');
$mostPopularNews->expiresAt(new \DateTime('tomorrow'));

缓存元素的命中和丢失 

使用缓存架构对于改善程序性能是非常重要的,但它也不应该成为程序运行的必须品。实际上,PSR-6标准声明了“缓存错误不应该导致程序错误”。

在实践中这意味着 getItem() 方法永远返回一个实现了 Psr\Cache\CacheItemInterface 接口的对象,哪怕在缓存元素并不存在时。所以,你毋须处理 null 返回值,你可以安全地存储 falsenull 这种缓存值。

为了决定返回的对象是否正确,缓存使用了命中和丢失的概念(the concept of hits and misses):

  • Cache Hits 发生在“当请求的元素在缓存中找到”时,它的值不被破坏或失效,而且它尚未过期;
  • Cache Misses 与命中相反,所以它们发生在“当元素没有在缓存中找到”时,它的值会被破坏或无效化,以任何理由,或者元素过期。

缓存元素对象定义了一个布尔值的 isHit() 方法以为cache hits返回 true

1
2
3
4
5
6
7
8
9
$latestNews = $cache->getItem('latest_news');
 
if (!$latestNews->isHit()) {
    // do some heavy computation / 做一些重载计算
    $news = ...;
    $cache->save($latestNews->set($news));
} else {
    $news = $latestNews->get();
}

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)