Сайт на Yii2 может работать быстро, но если каждый запрос к базе данных выполняется заново, даже самый мощный сервер начнёт тормозить. Кеширование — это как термос для кофе: один раз заварил, а пьёшь горячим весь день. В этой статье мы разберём, как построить систему кеширования данных в Yii2, чтобы страницы летали, а база отдыхала.
Зачем вообще кешировать данные в Yii2
Представь, что ты каждый раз, когда хочешь узнать время, идёшь в другой город за часами. Смешно, правда? А ведь именно так работает приложение без кеша: каждый запрос к странице заставляет базу данных снова и снова выполнять одни и те же тяжёлые запросы. Yii2 предоставляет мощный компонент cache, который умеет хранить данные в файлах, памяти или Redis. Но просто включить его недостаточно — нужно правильно организовать слои кеширования.
Основная идея: мы перехватываем результаты дорогих операций (запросы к БД, вызовы API, рендеринг блоков) и сохраняем их на время. При следующем запросе отдаём готовое, не напрягая сервер.
Настройка компонента cache
В Yii2 кеш настраивается в конфиге приложения. По умолчанию используется файловый кеш, но для продакшена лучше взять что-то пошустрее, например, Memcached или Redis. Вот пример конфигурации для Redis:
'components' => [
'cache' => [
'class' => 'yii\redis\Cache',
'redis' => [
'hostname' => 'localhost',
'port' => 6379,
'database' => 0,
],
'keyPrefix' => 'myapp_',
],
],
Если Redis нет, можно использовать yii\caching\FileCache или yii\caching\DbCache. Главное — не оставлять всё на самотёк.
keyPrefix для каждого проекта, чтобы кеш разных приложений не смешивался.
Три уровня кеширования: данные, фрагменты, страницы
В Yii2 можно кешировать на разных уровнях. Выбирайте под задачу:
| Уровень | Что кешируем | Инструмент Yii2 |
|---|---|---|
| Данные | Результаты запросов, вычисления | Yii::$app->cache->get()/set() |
| Фрагменты | HTML-блоки, виджеты | $this->beginCache()/endCache() |
| Страницы | Целые ответы | yii\filters\PageCache |
Начнём с самого простого — кеширования данных. Например, у нас есть тяжёлый запрос к таблице заказов:
$orders = Yii::$app->cache->get('all_orders');
if ($orders === false) {
$orders = Order::find()->with('user')->all();
Yii::$app->cache->set('all_orders', $orders, 3600); // кеш на час
}
return $orders;
Этот код проверяет, есть ли данные в кеше. Если нет — делает запрос и сохраняет результат на час. Всё просто.
Кеширование фрагментов: когда страница разная, а блок — нет
Иногда страница зависит от пользователя, но какой-то блок (например, список популярных товаров) одинаков для всех. Тут пригодится кеширование фрагментов. Внутри представления:
beginCache('popular_products', ['duration' => 3600])): ?>
= $product->name ?>
endCache(); endif; ?>
Yii2 сам сгенерирует ключ на основе имени блока и параметров. Если нужно учесть язык или категорию, добавьте variations:
$this->beginCache('popular_products', [
'duration' => 3600,
'variations' => [Yii::$app->language, $categoryId],
]);
dependency в кеше фрагментов, чтобы автоматически сбрасывать кеш при изменении данных. Например, DbDependency с SQL-запросом.
Кеширование страниц целиком: PageCache
Если страница полностью статична для всех (или почти всех), можно кешировать весь ответ. В контроллере добавляем фильтр:
public function behaviors()
{
return [
'pageCache' => [
'class' => 'yii\filters\PageCache',
'only' => ['index', 'view'],
'duration' => 7200,
'dependency' => [
'class' => 'yii\caching\DbDependency',
'sql' => 'SELECT MAX(updated_at) FROM product',
],
],
];
}
Теперь страницы index и view будут отдаваться из кеша 2 часа. Но как только в таблице product обновится запись, кеш сбросится автоматически. Удобно!
Продвинутые техники: теги и зависимости
Чтобы не сбрасывать весь кеш при малейшем изменении, используйте теги. Например, помечаем кеш тегом products:
Yii::$app->cache->set('product_list', $data, 3600, new TagDependency(['tags' => 'products']));
А при обновлении любого товара вызываем:
TagDependency::invalidate(Yii::$app->cache, 'products');
Это гибче, чем сбрасывать всё подряд. Также можно комбинировать зависимости: ChainedDependency позволяет объединить несколько условий.
Вот таблица с основными зависимостями Yii2:
| Класс | Когда использовать |
|---|---|
DbDependency |
Зависимость от результата SQL-запроса |
FileDependency |
Зависимость от времени изменения файла |
TagDependency |
Групповая инвалидация по тегам |
ChainedDependency |
Комбинация нескольких зависимостей |
Что в итоге
Построение системы кеширования в Yii2 — это не магия, а последовательность шагов. Настройте компонент cache, выберите уровни (данные, фрагменты, страницы), добавьте зависимости и теги для умного сброса. Начните с малого: закешируйте один тяжёлый запрос, замерьте скорость. Потом расширяйте. И помните: кеш — это компромисс между скоростью и актуальностью. Не кешируйте то, что меняется каждую секунду, если это критично.
Внедрив описанные приёмы, вы удивитесь, насколько быстрее станет ваш проект на Yii2. База данных скажет спасибо, а пользователи — тем более.


