Nicolas Grekas
Contributed by Nicolas Grekas in #17408

This is the last article in the "New in Symfony 3.1" series and it introduces the most important new feature of Symfony 3.1: the Cache component.

This new component is a strict implementation of the PSR-6: Caching Interface standard. You can use it to cache arbitrary content in your application and some Symfony components use it internally to improve their performance.

The following example shows how to create, save and delete information in a filesystem-based cache:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
use Symfony\Component\Cache\Adapter\FilesystemAdapter;

// available adapters: filesystem, apcu, redis, array, doctrine cache, etc.
$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');

The Cache component provides adapters for the most common caching backends (Redis, APCu), it's compatible with every Doctrine Cache adapter (Memcache, MongoDB, Riak, SQLite, etc.) and it also provides two special adapters (Proxy and Chain) for advanced setups.

For example, if your application uses Redis, the example shown above is still valid. You just need to change the instantiation of the cache adapter and leave the rest of the code unchanged:

1
2
3
4
use Symfony\Component\Cache\Adapter\RedisAdapter;

$cache = new RedisAdapter($redisConnection);
// ...

The documentation of the Cache component is already finished and it will be merged soon into the official Symfony docs.

Symfony Integration

The Cache component is ready to be used in any PHP application, but if you use the Symfony framework, the component is already integrated. Symfony defines two different cache pools: cache.app is where you store the information generated by your own application; cache.system is where Symfony components store their contents (e.g. the Serializer and Validator metadata).

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();
        }

        // ...
    }
}

If your server has APCu installed, the cache.system pool uses it. Otherwise, it falls back to the filesystem cache. For the cache.app pool is recommended to use a proper cache backend such as Redis:

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

You can also create your own custom cache pools and they can even be based on the configuration of the default cache.app pool:

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
Published in #Living on the edge