Кеширование
Кеш — временное хранилище готовых результатов. Если список популярных статей считается долгим запросом, его сохраняют в кеш и следующие минуты отдают оттуда, не обращаясь к базе. В 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() класса таблицы.