Введение в PSR-16: Кеширование на PHP с Примерами кода

PHP-FIG (PHP Framework Interop Group) разработала ряд стандартов PSR (PHP Standard Recommendations), включая PSR-16, который определяет интерфейс для простых кэшей данных. Кэширование — это эффективный способ улучшить производительность вашего веб-приложения, избегая повторных вычислений или обращений к источникам данных.

Что такое PSR-16?

PSR-16 — это стандартный интерфейс для кэшей простых данных в PHP. Этот стандарт описывает, как реализовать кэширование ваших данных в памяти, предоставляя единый интерфейс для реализации и работы с кэшем. Это позволяет приложениям легко переключаться между различными реализациями кэша, не изменяя код приложения.

Реализация на обычных массивах PHP

Давайте рассмотрим пример простой реализации PSR-16 на основе обычных массивов PHP. В реальных проектах вы, вероятно, захотите использовать более мощные инструменты, такие как Memcached или Redis, но для целей демонстрации обычный массив подходит отлично.

<?php

use Psr\SimpleCache\CacheInterface;

class ArrayCache implements CacheInterface
{
    private $data = [];

    public function get(string $key, mixed $default = null): mixed
    {
        return $this->has($key) ? $this->data[$key] : $default;
    }

    public function set(string $key, mixed $value, null|int|\DateInterval  $ttl = null): bool
    {
        $this->data[$key] = $value;
          return true;
    }

    public function delete(string $key): true
    {
        unset($this->data[$key]);
        return true;
    }

    public function clear() : bool
    {
        $this->data = [];
        return true;
    }

    public function getMultiple(iterable $keys, mixed $default = null): iterable
    {
        $result = [];
        foreach ($keys as $key) {
            $result[$key] = $this->get($key, $default);
        }
        return $result;
    }

    public function setMultiple(iterable $values,null|int|\DateInterval $ttl = null): bool 
    {
        foreach ($values as $key => $value) {
            $this->set($key, $value, $ttl);
        }
    }

    public function deleteMultiple(iterable $keys): bool
    {
        foreach ($keys as $key) {
            $this->delete($key);
        }
    }

    public function has(string $key): bool
    {
        return isset($this->data[$key]);
        
    }

}

// Пример использования с Iterator и yield
$cache = new ArrayCache();

// Запись в кэш
$cache->set('user:1', ['id' => 1, 'name' => 'John Doe']);
$cache->set('user:2', ['id' => 2, 'name' => 'Jane Doe']);
$cache->set('user:3', ['id' => 3, 'name' => 'Bob Smith']);

// Итерация по ключам с использованием yield
foreach ($cache->getMultiple(['user:1', 'user:2', 'user:3']) as $key) {
    echo "Key: $key, Value: ";
    var_dump($cache->get($key));
}


Пример с использованием yield для ленивой загрузки

Метод getMultiple и iterateKeys используют yield для ленивой загрузки значений из кэша при итерации по ключам. Это может быть особенно полезно при работе с большими объемами данных, где загрузка всех значений сразу может потребовать больших ресурсов памяти.

<?php

use Psr\SimpleCache\CacheInterface;

class ArrayCache implements CacheInterface
{
    private $data = [];

    // ... предыдущие методы остаются неизменными

    public function getMultiple(iterable $keys, mixed $default = null): iterable
    {
        foreach ($keys as $key) {
            yield $key => $this->get($key, $default);
        }
    }
}

// Пример использования
$cache = new ArrayCache();

// Запись в кэш
$cache->set('user:1', ['id' => 1, 'name' => 'John Doe']);
$cache->set('user:2', ['id' => 2, 'name' => 'Jane Doe']);
$cache->set('user:3', ['id' => 3, 'name' => 'Bob Smith']);

// Итерация по ключам с использованием yield
foreach ($cache->getMultiple(['user:1', 'user:2', 'user:3']) as $key => $value) {
    echo "Key: $key, Value: ";
    var_dump($value);
}