Gestion du cache

Gestion du cache

29 December 2022

La gestion du cache est un élément important dans le développement d'applications Web. Elle permet de stocker des données de manière temporaire dans la mémoire, ce qui peut accélérer considérablement les performances de l'application en réduisant le temps de chargement des pages et en réduisant la charge sur les bases de données et les autres ressources de l'application.

Symfony inclut un système de gestion de cache intégré qui permet aux développeurs de mettre en cache des données de différentes manières.

Il existe plusieurs types de cache disponibles dans Symfony :

  • Le cache d'objets : permet de mettre en cache des objets PHP afin de réduire le temps de chargement de l'application.
  • Le cache de templates : permet de mettre en cache le rendu des templates pour accélérer le chargement des pages.
  • Le cache de routes : permet de mettre en cache les routes de l'application, ce qui peut accélérer considérablement les performances lorsque vous avez un grand nombre de routes.

Pour utiliser le cache dans Symfony, vous devez d'abord définir un "service de cache" dans votre fichier de configuration. Vous pouvez ensuite utiliser ce service de cache dans votre code en injectant le service de cache dans votre classe. Vous pouvez ensuite utiliser les méthodes du service de cache pour enregistrer et récupérer des données du cache.

Créer un cache avec un FrameworkBundle

Pour utiliser le système de cache de Symfony avec le FrameworkBundle, vous devez d'abord configurer un "service de cache" dans votre fichier de configuration (généralement le fichier config/packages/cache.yaml).

Voici un exemple de configuration qui utilise le cache de fichiers pour stocker les données :

framework:
    cache:
        app: cache.adapter.filesystem

Cette configuration va créer un service de cache nommé cache.app qui utilise le cache de fichiers pour stocker les données. Vous pouvez également configurer d'autres options, comme le répertoire où les fichiers de cache seront stockés :

framework:
    cache:
        app:
            adapter: cache.adapter.filesystem
            path: '%kernel.cache_dir%/cache'

Une fois que vous avez configuré le service de cache, vous pouvez l'injecter dans votre contrôleur et utiliser les méthodes du service de cache pour enregistrer et récupérer des données du cache :

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Cache\Adapter\AdapterInterface;

class MyController extends AbstractController
{
    public function index(AdapterInterface $cache)
    {
        // Récupération d'un élément du cache
        $item = $cache->getItem('key');
        if (!$item->isHit()) {
            // Si l'élément n'est pas dans le cache, on le charge depuis la base de données ou un autre service
            $data = ...;
            // Enregistrement de l'élément dans le cache
            $item->set($data);
            $cache->save($item);
        }
        // Récupération des données depuis le cache
        $data = $item->get();

        // Utilisation des données dans le template
        return $this->render('my_template.html.twig', [
            'data' => $data,
        ]);
    }
}

Il est important de noter que le cache n'est pas une solution miracle pour améliorer les performances de votre application. Vous devez évaluer si l'utilisation du cache est appropriée pour votre application et mesurer ses performances pour vous assurer qu'elle améliore réellement les performances de votre application.

Création d'une chaîne de caches

Il est possible de définir une chaîne de caches dans Symfony afin de mettre en cache les données dans plusieurs caches différents. Cela peut être utile si vous souhaitez utiliser un cache en mémoire pour les données qui doivent être chargées rapidement, tout en utilisant un cache de fichiers ou une base de données pour les données qui ont une durée de vie plus longue.

Voici un exemple de configuration qui définit un cache en mémoire et un cache de fichiers :

services:
    cache.app.memory:
        class: Symfony\Component\Cache\Adapter\ArrayAdapter
    cache.app.filesystem:
        class: Symfony\Component\Cache\Adapter\FilesystemAdapter
        arguments:
            - '%kernel.cache_dir%/cache'

Ensuite, vous pouvez définir une chaîne de caches en utilisant la classe ChainAdapter de Symfony. La chaîne de caches va essayer de récupérer les données dans chaque cache de la chaîne, jusqu'à ce qu'elle trouve une valeur valide ou qu'elle atteigne la fin de la chaîne :

services:
    cache.app:
        class: Symfony\Component\Cache\Adapter\ChainAdapter
        arguments:
            - ['@cache.app.memory', '@cache.app.filesystem']

Utilisation des balises de mise en cache

Symfony propose un mécanisme de mise en cache de template basé sur des balises de mise en cache qui vous permettent de mettre en cache des parties de votre template.

Voici comment utiliser les balises de mise en cache dans un template Twig :

{% cache 'my_cache_key' %}
    {# Contenu du cache #}
{% endcache %}

La première fois que le template est rendu, le contenu du cache sera généré et mis en cache avec la clé de cache spécifiée. Lorsque le template est rendu ultérieurement, le contenu du cache sera utilisé à la place du contenu généré.

Vous pouvez également spécifier un délai de validité pour le cache en utilisant l'option ttl :

{% cache 'my_cache_key' ttl=3600 %}
    {# Contenu du cache valide pendant 1 heure #}
{% endcache %}

Chiffrer le cache

Il est possible de chiffrer les données du cache dans Symfony afin de protéger les données sensibles stockées dans le cache.

Pour chiffrer les données du cache, vous devez utiliser un "adapter de cache chiffré". Symfony propose un adapter de cache chiffré basé sur la librairie PHP defuse/php-encryption.

Voici comment configurer un service de cache chiffré dans Symfony :

services:
    cache.app:
        class: Symfony\Component\Cache\Adapter\EncrypterAdapter
        arguments:
            - '@cache.app.filesystem'
            - '%env(APP_SECRET)%'

Dans cet exemple, nous utilisons le service de cache de fichiers cache.app.filesystem comme cache de base et nous spécifions une clé de chiffrement en utilisant une variable d'environnement APP_SECRET.

Vous pouvez maintenant injecter le service de cache chiffré cache.app dans votre contrôleur et utiliser les méthodes du service de cache pour enregistrer et récupérer des données du cache de manière transparente : les données seront automatiquement chiffrées et déchiffrées lorsqu'elles sont enregistrées et récupérées du cache.

Effacer le cache

Il existe plusieurs façons de vider le cache dans Symfony.

Voici comment vider le cache depuis la ligne de commande en utilisant la commande cache:clear :

php bin/console cache:clear
# symfony console cache:clear

Cette commande effacera le cache de l'application et régénérera les fichiers de cache nécessaires.

Vous pouvez également effacer le cache depuis votre code en utilisant les méthodes du service de cache. Par exemple, voici comment effacer le cache d'objets dans un contrôleur :

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;

class MyController extends AbstractController
{
    public function clearCache(FilesystemAdapter $cache)
    {
        $cache->clear();
    }
}

Il est important de noter que l'effacement du cache peut avoir un impact sur les performances de votre application. Vous devez donc être conscient de l'utilisation que vous faites de cette fonctionnalité et ne l'utiliser que lorsque cela est vraiment nécessaire.

Bonus : Configurer le cache avec Redis

Pour configurer le cache de votre application Symfony avec Redis, vous devez d'abord installer le client PHP Redis en utilisant Composer :

composer require predis/predis

Ensuite, vous devez configurer le service de cache Redis dans votre fichier de configuration (généralement le fichier config/packages/cache.yaml). Voici un exemple de configuration qui utilise Redis comme cache :

services:
    cache.app:
        class: Symfony\Component\Cache\Adapter\RedisAdapter
        arguments:
            - '@predis'
            - 'cache_prefix'

Dans cet exemple, nous avons injecté le service predis (le client Redis) dans notre service de cache Redis et nous avons spécifié un préfixe de clé de cache (cache_prefix) qui sera utilisé pour toutes les clés de cache stockées dans Redis.

Il est important de noter que vous devez avoir un serveur Redis en cours d'exécution et accessible depuis votre application pour pouvoir utiliser le cache Redis. L'installation d'un serveur Redis fera l'objet d'un autre article.

Configurer la connexion au serveur Redis

Vous pouvez configurer le client Predis en définissant le service predis dans votre fichier de configuration. Voici un exemple de configuration qui utilise Predis avec une connexion par défaut au serveur Redis localhost sur le port 6379 :

services:
    predis:
        class: Predis\Client
        arguments:
            - { scheme: 'tcp', host: '127.0.0.1', port: 6379 }

Vous pouvez également spécifier plusieurs options de connexion en utilisant un tableau associatif pour la valeur de l'argument. Par exemple, voici comment configurer Predis avec une connexion sécurisée à un serveur Redis distant :

services:
    predis:
        class: Predis\Client
        arguments:
            - { scheme: 'tls', host: 'redis.example.com', port: 6379, password: 'my_password' }

Une fois que vous avez configuré le service Predis, vous pouvez l'injecter dans votre code et utiliser les méthodes de la classe Predis\Client pour effectuer des opérations sur votre serveur Redis.

Effacer le cache Redis

Voici comment effacer le cache Redis dans Symfony :

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Cache\Adapter\RedisAdapter;

class MyController extends AbstractController
{
    public function clearCache(RedisAdapter $cache)
    {
        // Effacement du cache Redis
        $cache->clear();
    }
}

Nous avons injecté le service RedisAdapter pour pouvoir effacer le cache.