Кеширование
Тяжёлый запрос к базе или обращение к внешнему сервису незачем выполнять при каждом открытии страницы. Результат сохраняют в кеше и какое-то время отдают готовым. В Symfony для этого есть сервис CacheInterface.
Получить или вычислить
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
#[Route('/', name: 'home')]
public function index(CacheInterface $cache, PostRepository $posts): Response
{
$popular = $cache->get('popular_posts', function (ItemInterface $item) use ($posts) {
$item->expiresAfter(3600);
return $posts->findPopular(10);
});
return $this->render('home.html.twig', ['popular' => $popular]);
}Метод get() ищет запись по ключу. Если её нет, выполняет функцию, сохраняет результат и возвращает его. expiresAfter() задаёт срок жизни в секундах.
Удаление
Когда данные изменились, запись удаляют — при следующем обращении она вычислится заново:
$cache->delete('popular_posts');Ключи с параметрами
$post = $cache->get('post_' . $id, function (ItemInterface $item) use ($id, $posts) {
$item->expiresAfter(600);
return $posts->find($id);
});Метки
Метки позволяют сбросить сразу группу записей:
use Symfony\Contracts\Cache\TagAwareCacheInterface;
public function index(TagAwareCacheInterface $cache): Response
{
$popular = $cache->get('popular_posts', function (ItemInterface $item) {
$item->tag(['posts']);
return $this->posts->findPopular(10);
});
// …
}$cache->invalidateTags(['posts']);Где хранится кеш
По умолчанию — в файлах папки var/cache. Для нагруженных сайтов подключают Redis:
# config/packages/cache.yaml
framework:
cache:
app: cache.adapter.redis
default_redis_provider: '%env(REDIS_URL)%'Код приложения при этом не меняется.
Очистка
php bin/console cache:pool:clear cache.app
php bin/console cache:clearПервая команда удаляет данные приложения, вторая — служебный кеш Symfony: настройки, маршруты, шаблоны.
Кеширование ответа
Можно кешировать страницу целиком — в браузере и на промежуточных серверах:
use Symfony\Component\HttpKernel\Attribute\Cache;
#[Route('/about', name: 'about')]
#[Cache(maxage: 3600, public: true)]
public function about(): Response
{
return $this->render('about.html.twig');
}Так кешируют только страницы, одинаковые для всех посетителей.
Частая ошибка
Кеш без удаления показывает устаревшие данные: статью изменили, а на главной ещё час висит старый заголовок. Для каждой записи в кеше решите, когда она становится неверной, и удаляйте её в этот момент — после сохранения сущности. И помните о ключах: символы {}()/\@: в них запрещены.