Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Кеширование

Тяжёлый запрос к базе или обращение к внешнему сервису незачем выполнять при каждом открытии страницы. Результат сохраняют в кеше и какое-то время отдают готовым. В 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');
}

Так кешируют только страницы, одинаковые для всех посетителей.

Частая ошибка

Кеш без удаления показывает устаревшие данные: статью изменили, а на главной ещё час висит старый заголовок. Для каждой записи в кеше решите, когда она становится неверной, и удаляйте её в этот момент — после сохранения сущности. И помните о ключах: символы {}()/\@: в них запрещены.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.