Encodera

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

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

Оглавление

Кеширование

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

Где настроен

Хранилища описаны в разделе Cache файла config/app.php. Хранилище default в новом проекте — файлы в папке tmp/cache, ничего устанавливать не нужно.

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

// src/Controller/ArticlesController.php
use Cake\Cache\Cache;
 
public function stats(): void
{
    $total = Cache::read('articles_total');
 
    if ($total === null) {
        $total = $this->Articles->find()->count();
 
        Cache::write('articles_total', $total);
    }
 
    $this->set(compact('total'));
}

read() возвращает значение по ключу или null, если его нет. Тогда значение считают и сохраняют методом write(). Первый запрос страницы /articles/stats обратится к базе, следующие — возьмут число из кеша.

Короче: remember

$popular = Cache::remember('popular_articles', function () {
    return $this->Articles->find()
        ->orderByDesc('views')
        ->limit(10)
        ->toArray();
});

remember() делает то же одним вызовом: возвращает значение из кеша, а если его нет — выполняет функцию и сохраняет результат. В кеш кладут массив — toArray(), а не сам запрос.

Удаление

Cache::delete('popular_articles');

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

Методы

МетодЧто делает
Cache::write($key, $value)Сохраняет значение
Cache::read($key)Читает значение или null
Cache::remember($key, $callback)Читает или вычисляет и сохраняет
Cache::delete($key)Удаляет значение
Cache::clear()Очищает хранилище целиком

Срок жизни

Добавьте в config/app.php своё хранилище с коротким сроком:

// config/app.php
'Cache' => [
    // ... хранилища, которые уже были в файле
 
    'short' => [
        'className' => \Cake\Cache\Engine\FileEngine::class,
        'duration' => '+10 minutes',
        'path' => CACHE,
    ],
],

Имя хранилища передают последним аргументом:

Cache::write('articles_total', $total, 'short');
$total = Cache::read('articles_total', 'short');

Через десять минут значение устареет, и read() снова вернёт null.

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

КлассГде хранит
FileEngineФайлы в tmp/cache
RedisEngineСервер Redis
MemcachedEngineСервер Memcached
ArrayEngineПамять на время одного запроса

Код с Cache::read() и Cache::write() при смене хранилища не меняется.

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

bin/cake cache clear_all

Команда очищает все хранилища — в том числе служебный кеш самого фреймворка.

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

Статью изменили, а на странице старые данные: кеш ещё не истёк. Кешируя результат, сразу решите, когда он сбрасывается, — по сроку duration или вызовом Cache::delete() в методе afterSave() класса таблицы.

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

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