Encodera

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

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

Оглавление

Кеширование

Кеш — временное хранилище готовых результатов. Если список свежих статей с авторами собирается долго, его вычисляют один раз, кладут в кеш и следующие несколько минут отдают оттуда, не обращаясь к базе.

Где настраивается кеш

Кеш — компонент cache. Он уже описан в config/web.php:

// config/web.php
'components' => [
    'cache' => [
        'class' => 'yii\caching\FileCache',
    ],
],

FileCache хранит данные в файлах в папке runtime/cache, ничего дополнительно устанавливать не нужно.

Запись и чтение

// controllers/PostController.php
public function actionLatest(): string
{
    $posts = Yii::$app->cache->getOrSet('latest-posts', function () {
        return Post::find()->orderBy(['created_at' => SORT_DESC])->limit(5)->all();
    }, 600);
 
    return $this->render('index', ['posts' => $posts]);
}

getOrSet() ищет в кеше значение с ключом latest-posts. Если его нет, выполняет функцию, сохраняет результат на 600 секунд и возвращает его. Первое открытие страницы выполнит запрос к базе, следующие десять минут — нет; это видно по числу запросов в панели отладки.

Методы кеша

ВызовЧто делает
$cache->set('key', $value, 600)Сохраняет значение на 600 секунд
$cache->get('key')Возвращает значение или false, если его нет
$cache->getOrSet('key', $callable, 600)Читает, а при отсутствии вычисляет и сохраняет
$cache->delete('key')Удаляет значение
$cache->flush()Очищает весь кеш

Сброс при изменении

Устаревший кеш удаляют, когда данные меняются. Удобное место — метод модели, который Yii вызывает после каждого сохранения:

// models/Post.php
public function afterSave($insert, $changedAttributes): void
{
    parent::afterSave($insert, $changedAttributes);
 
    Yii::$app->cache->delete('latest-posts');
}

После создания или изменения статьи список свежих статей пересчитается при следующем открытии страницы.

Кеш запросов

Результат отдельного запроса к базе кешируют методом cache():

$posts = Post::find()->where(['status' => 1])->cache(60)->all();

В течение минуты одинаковый запрос будет возвращать сохранённые строки.

Кеш части шаблона

Готовую разметку блока тоже можно сохранить:

<?php
// views/layouts/main.php
?>
 
<?php if ($this->beginCache('sidebar', ['duration' => 300])): ?>
    <aside>
        <!-- тяжёлый блок: облако тегов, последние комментарии -->
    </aside>
    <?php $this->endCache(); ?>
<?php endif; ?>

Первый раз блок выполняется и сохраняется, следующие пять минут Yii подставляет готовую разметку и код внутри не выполняет.

Очистка из консоли

php yii cache/flush-all

Команда очищает все компоненты кеша, описанные в config/console.php.

Другие хранилища

На нагруженных сайтах файлы заменяют хранилищем в памяти — меняется только класс компонента, код остаётся прежним: yii\caching\MemCache для Memcached, yii\redis\Cache из пакета yiisoft/yii2-redis для Redis.

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

Метод get() возвращает false, когда значения нет. Если в кеш положить само значение false или проверять результат через if (!$value), пустой массив и ноль будут приняты за промах, и кеш не сработает. Сравнивайте строго: if ($value === false) — или пользуйтесь getOrSet().

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

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