Обʼєкти кешу

Дата оновлення перекладу 2024-04-30

Обʼєкти кешу

Обʼєкти кешу - це інформаційні одиниці, які зберігаються в кеші у вигляді пари ключ/значення. В компоненті Кеш вони представлені класом CacheItem. Вони використовуються як в інтерфейсах Контрактах кешу, так і в інтерфейсі PSR-6.

Ключі та значення обʼєктів кешу

Ключ обʼєкта кешу - це простий рядок, який діє так само, як його ідентифікатор, тому він повинен бути унікальним для кожного пулу кешу. Ви можете вільно обирати ключі, але вони повинні містити лише літери (A-Z, a-z), цифри (0-9) та символи _ і .. Інші розповсюджені символи (на кшталт {, }, (, ), /,
\ і @) зарезервовані стандартом PSR-6 для подальшого використання.

Значення обʼєкта кешу може бути будь-якими даними, представленими типом, який можна серіалізувати PHP, наприклад, звичайними типами (рядок, число, булеве значення, null), масивами і обʼєктами.

Створення обʼєктів кешу

Єдиний спосіб створити обʼєкти кешу - через пули кешу. При використанні Контрактів Кеша, вони передаються як аргументи зворотному виклику перерахунку:

1
2
3
4
// обʼєкт пулу $cache був створений раніше
$productsCount = $cache->get('stats.products_count', function (ItemInterface $item): string {
    // [...]
});

При використанні PSR-6, вони створюються методом пулу кешуу getItem($key):

1
2
// обʼєкт пулу $cache був створений раніше
$productsCount = $cache->getItem('stats.products_count');

Далі, використайте метод Psr\\Cache\\CacheItemInterface::set, щоб встановити дані, що зберігаються в обʼєкті кешу:

// збереження простого числа $productsCount->set(4711); $cache->save($productsCount);

// збереження масиву $productsCount->set([ 'category1' => 4711, 'category2' => 2387, ]); $cache->save($productsCount);

Ключ і значення будь-якого заданого обʼєкта кешу можна отримати за допомогою існуючих методів гетера:

1
2
3
4
$cacheItem = $cache->getItem('exchange_rate');
// ...
$key = $cacheItem->getKey();
$value = $cacheItem->get();

Строк дії обʼєкта кешу

За замовчуванням, обʼєкти кешу зберігаються постійно. На практиці, це "постійне зберігання" може сильно відрізнятися, в залежності від використовуваного типу кешу, як пояснюється у статті Пули кешу та підтримувані адаптери.

Однак, у деяких додатках розповсюджено використання обʼєктів кешу з коротшим життєвим циклом. Розгляньте, наприклад, додаток, який кешує останні новини лише на одну хвилину. У таких випадках, використайте метод expiresAfter(), щоб встановити кількість секунд для кешування обʼєкта:

1
2
3
4
$latestNews->expiresAfter(60);  // 60 секунд = 1 хвилина

// цей метод також приймає екземпляри \DateInterval
$latestNews->expiresAfter(DateInterval::createFromDateString('1 hour'));

Обʼєкти кешу визначають інший повʼязаний метод під назвою expiresAt(), щоб встановити точну дату та час закінчення строку дії обʼєкта:

1
$mostPopularNews->expiresAt(new \DateTime('tomorrow'));

Попадання та промахи обʼєктів кешу

Використання механізму кешу важливо для покращення продуктивності додатку, але не повинно бути обовʼязковим для роботи додатку. Насправді, стандарт PSR-6 вказує, що помилки кешування не повинні призводити до помилок додатку.

На практиці це означає, що метод getItem() завжди повертає обʼєкт, що реалізує інтерфейс Psr\Cache\CacheItemInterface, навіть коли обʼєкт кешу не існує. Відповідно, вам не потрібно розбиратися зі зворотними значеннями null і ви можете безпечно зберігати значення кешу, на кшталт false і null.

Для того, щоб вирішити, чи правильний повернений обʼєкт, кеші використовують концепт попадань та промахів:

  • Кеш-попадання виникають, коли запитаний обʼєкт знайдено в кешу, його значення не пошкоджене та валідне, і він не прострочений;
  • Кеш-промахи є протилежністю попадань, тому вони виникають, коли обʼєкт не знайдено в кеші, його значення пошкоджене або невалідно за якоїсь причини, або ж обʼєкт прострочений.

Одиниці обʼєктів кешу визначають булевий метод isHit(), який повертає true для кеш-попадань:

1
2
3
4
5
6
7
8
9
$latestNews = $cache->getItem('latest_news');

if (!$latestNews->isHit()) {
    // зробити складні обчислення
    $news = ...;
    $cache->save($latestNews->set($news));
} else {
    $news = $latestNews->get();
}