Encodera

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

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

Оглавление

Кеширование

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

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

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