By Ismael Ambrosi @iambrosi

The cache is a very important part of your Symfony application as it helps your web server to perform better by not executing unnecessary code on every request, this is especially true if your server is running with limited resources. Cache warming allows you to cache specific data in your application through the use of a CacheWarmer. Symfony 2 includes a cache warmer that helps you to store parts of your application in cache, before the application becomes available to the user.

The CacheWarmer must implement a warmup, which will be ran by Symfony and will automatically re-create a cache of your app. It can also be manually executed with the command cache:warmup or when you clear your cache with cache:clear (!!! without the --no-warmup option).

Creating the Warmer

A CacheWarmer must be created as a service that implements the interface Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface. Take a look at the Service Container section of the Symfony manual on how to create services in Symfony2.

The CacheWarmerInterface interface allows us to implement two methods, warmUp and isOptional. The first method will create the cache and the second method tells the warmer if it can be ignored under certain conditions or it has to be executed without any exceptions.

# src/Acme/DemoBundle/CacheWarmer/MyCacheWarmer.php
namespace Acme\DemoBundle\CacheWarmer;

use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;

class MyCacheWarmer implements CacheWarmerInterface
{
    /**
     * Warms up the cache.
     *
     * @param string $cacheDir The cache directory
     */
    public function warmUp($cacheDir)
    {
        // Process your cache content
        $cacheContent = 'Content to be cached';

        // Stores the cache
        file_put_contents($cacheDir.'/file.php', $cacheContent);
    }

    /**
     * Checks whether this warmer is optional or not.
     *
     * Optional warmers can be ignored on certain conditions.
     *
     * A warmer should return true if the cache can be
     * generated incrementally and on-demand.
     *
     * @return Boolean true if the warmer is optional, false otherwise
     */
    public function isOptional()
    {
        return true;
    }
}

You can also extend the class Symfony\Component\HttpKernel\CacheWarmer\CacheWarmer, which already has a method for managing the creation of cache file or files. By extending this class, you are implementing the previous mentioned interface.

# src/Acme/DemoBundle/CacheWarmer/MyCacheWarmer.php
namespace Acme\DemoBundle\CacheWarmer;

use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmer;

class MyCacheWarmer extends CacheWarmer
{

    /**
     * Warms up the cache.
     *
     * @param string $cacheDir The cache directory
     */
    public function warmUp($cacheDir)
    {
        // Process your cache content
        $cacheContent = 'Content to be cached';

        // Stores the cache
        $this->writeCacheFile($cacheDir.'/file.php', $cacheContent);
    }

Creating the service

Once you create your class, you have to notify the Service Container that a new Cache Warmer has been created, so it can be executed. You can do so by adding your class as a service, including the tag kernel.cache_warmer.

<!-- src/Acme/DemoBundle/Resources/config/services.xml -->
<parameters>
    <!-- ... -->
    <parameter key="my_cache_warmer.class">Acme\DemoBundle\CacheWarmer\MyCacheWarmer</parameter>
</parameters>

<services>
    <service id="my_cache_warmer" class="%my_cache_warmer.class%">
        <tag name="kernel.cache_warmer">
    </service>
</services>

Now, every time your Symfony project warms the cache, your Warmer will be executed, creating your own cache.