Кеширование
Кеш — временное хранилище готовых результатов. Если что-то долго вычисляется или запрашивается из базы, результат сохраняют и следующие запросы получают его мгновенно. В Laminas за это отвечает пакет laminas-cache, а место хранения — файлы, память, Redis — задаёт отдельный пакет-адаптер.
Установка
composer require laminas/laminas-cache laminas/laminas-cache-storage-adapter-filesystemВторой пакет хранит кеш в файлах. Согласитесь вписать в config/modules.config.php модули Laminas\Cache и Laminas\Cache\Storage\Adapter\Filesystem.
Настройка хранилища
Хранилища описывают в разделе caches файла config/autoload/global.php:
// config/autoload/global.php
use Laminas\Cache\Storage\Adapter\Filesystem;
return [
'caches' => [
'BlogCache' => [
'adapter' => Filesystem::class,
'options' => [
'cache_dir' => 'data/cache',
'ttl' => 600,
],
],
],
];| Ключ | Значение |
|---|---|
BlogCache | Имя сервиса, под которым хранилище лежит в контейнере |
adapter | Где хранить данные |
cache_dir | Папка для файлов кеша (она есть в заготовке) |
ttl | Сколько секунд запись считается свежей |
Сервис с кешем
Создайте сервис, который считает статьи и запоминает результат:
// module/Blog/src/Service/PostCounter.php
namespace Blog\Service;
use Blog\Model\PostTable;
use Laminas\Cache\Storage\StorageInterface;
class PostCounter
{
public function __construct(
private PostTable $posts,
private StorageInterface $cache,
) {}
public function count(): int
{
$cached = $this->cache->getItem('post_count');
if ($cached !== null) {
return (int) $cached;
}
$count = count($this->posts->fetchAll());
$this->cache->setItem('post_count', (string) $count);
return $count;
}
}getItem() возвращает null, если записи нет или она устарела. Тогда значение вычисляется и сохраняется методом setItem().
Хранилище названо в настройках строкой, а не классом, поэтому фабрику пишут вручную:
// module/Blog/src/Service/PostCounterFactory.php
public function __invoke(ContainerInterface $container): PostCounter
{
return new PostCounter(
$container->get(PostTable::class),
$container->get('BlogCache'),
);
}Зарегистрируйте PostCounter с этой фабрикой в service_manager и передайте сервис в контроллер. Первый вызов $this->postCounter->count() выполнит запрос, а следующие десять минут число будет браться из файла в data/cache.
Сброс кеша
Когда данные меняются, запись удаляют, чтобы не показывать устаревшее число:
public function reset(): void
{
$this->cache->removeItem('post_count');
}Вызывайте reset() после добавления и удаления статьи.
Методы хранилища
| Метод | Что делает |
|---|---|
getItem($key) | Читает запись или возвращает null |
setItem($key, $value) | Сохраняет запись |
hasItem($key) | Проверяет, есть ли свежая запись |
removeItem($key) | Удаляет запись |
Файловый адаптер хранит строки. Чтобы класть в кеш массивы, значение превращают в строку функцией json_encode() и обратно — json_decode(), либо подключают к хранилищу плагин serializer из пакета laminas-serializer.
Частая ошибка
Кеш, который не сбрасывают при изменении данных, показывает старые значения до конца срока ttl: статья добавлена, а счётчик прежний. Для каждой записи кеша заранее решите, какое действие делает её устаревшей, и вызывайте в нём removeItem().