本文是“Symfony 3.1新内容” 系列的最后一篇文章(译注:后续新功能介绍将以3.2为主),隆重介绍Symfony 3.1中最重要的新功能:Cache component

这个新组件,严格执行了PSR-6:Caching Interface缓存接口标准。你可以用它来缓存程序中的任意内容,而另外一些Symfony组件也在使用它以改进性能。

下面的例程展示了如何创建、存储和删除基于文件系统(filesystem-based)的缓存信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
 
// available adapters: filesystem, apcu, redis, array, doctrine cache, etc.
// 可用的缓存适配器有:filesystem、apcu、redis、array、doctrine,等等
$cache = new FilesystemAdapter();
 
// create a new item getting it from the cache
// 从缓存中得到并创建一个新元素
$numProducts = $cache->getItem('stats.num_products');
 
// assign a value to the item and save it
// 对新元素赋值然后存储
$numProducts->set(4711);
$cache->save($numProducts);
 
// retrieve the cache item
// 取出缓存元素
$numProducts = $cache->getItem('stats.num_products');
if (!$numProducts->isHit()) {
    // ... item does not exists in the cache
}
// retrieve the value stored by the item
// 取出存在元素中的值
$total = $numProducts->get();
 
// remove the cache item
// 删除缓存元素
$cache->deleteItem('stats.num_products');

缓存组件针对常见的缓存后端(Redis、APCu等)提供适配器,并兼容任何一个Doctrine的缓存适配器(Memcache、MongoDB、Riak、SQLite等等)。更提供了两个特殊适配器(Proxy和Chain)以便进行高级设置。

例如,你的程序要用Redis,上面的例程仍然有效。你只需改变缓存适配器的实例,其他所有代码皆不用动:

1
2
3
4
use Symfony\Component\Cache\Adapter\RedisAdapter;
 
$cache = new RedisAdapter($redisConnection);
// ...

缓存组件的文档已经完成,被合并之后即进入Symfony官方文档库。

与Symfony整合

缓存组件可以用在任何PHP程序中,但如果你正在使用Symfony框架,该组件已经整合完毕。Symfony定义了两个缓存池:cache.app是用来存储你的程序生成的信息的;cache.system则是Symfony组件用来存储它们的内容的(比如Serializer和Validator的元数据)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// src/AppBundle/Controller/BlogController.php
class BlogController extends Controller
{
    public function indexAction()
    {
        $cachedCategories = $this->get('cache.app')->getItem('categories');
        if (!$cachedCategories->isHit()) {
            $categories = ... // fetch categories from the database 从数据库里取出分类
            $cachedCategories->set($categories);
            $this->get('cache.app')->save($cachedCategories);
        } else {
            $categories = $cachedCategories->get();
        }
 
        // ...
    }
}

如果你的服务器安装了APCu,cache.system池将使用它。否则,它将回滚到filesystem缓存。对于cache.app池,推荐使用合适的后端缓存系统比如Redis:

1
2
3
4
5
# app/config/config_prod.yml
framework:
    cache:
        app: cache.adapter.redis
        default_redis_provider: "redis://localhost"

你也可以创建自己的自定义缓存池,甚至可以让它们基于默认的cache.app池的配置来建立:

1
2
3
4
5
6
7
8
# app/config/config_prod.yml
framework:
    cache:
        # ...
        pools:
            app.cache.customer:
                adapter: cache.app
                default_lifetime: 600