Обʼєкты кеша

Дата оновлення перекладу 2022-11-11

Обʼєкты кеша

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

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

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

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

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

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

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

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

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

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

1
2
3
4
5
6
7
8
9
10
// збереження простого числа
$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();
}