Кешування фрагментів

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

Для кешування фрагментів використовуйте наступний код у представленні:

if ($this->beginCache($id)) {

    // ... тут створюємо зміст ...

    $this->endCache();
}

Таким чином, розташуйте логіку генерації вмісту у комбінацію викликів [[yii\base\View::beginCache()|beginCache()]] та [[yii\base\View::endCache()|endCache()]]. Якщо вміст буде знайдено у кеші, [[yii\base\View::beginCache()|beginCache()]] відобразить закешований вміст і поверне false, оминаючи генерацію вмісту. В іншому випадку, буде виконано логіку генерації вмісту і з викликом [[yii\base\View::endCache()|endCache()]] згенерований вміст буде записаний до кешу.

Подібно до кешування даних, для кешування фрагментів необхідний унікальний ідентифікатор для визначення кешувального фрагмента.

Параметри кешування

Ви можете вказати додаткові параметри про кешуванні фрагментів, передавши масив опцій в якості другого параметра метода [[yii\base\View::beginCache()|beginCache()]]. За лаштунками, цей масив параметрів буде використано для налаштування віджета [[yii\widgets\FragmentCache]], який реалізує фактичну функціональність кешування фрагментів.

Тривалість

Мабуть найбільш часто використовуваною опцією кешування фрагмента є [[yii\widgets\FragmentCache::duration|duration]]. Вона визначає на скільки секунд зміст може залишатися дійсним у кеші. Код нижче кешує фрагмент не більше, ніж на одну:

if ($this->beginCache($id, ['duration' => 3600])) {

    // ... тут створюємо зміст ...

    $this->endCache();
}

Якщо опцію тривалості не задано, то вона прийме значенне за замовчування (60), що означає, що вміст в кеші стане недійсним через 60 секунд.

Залежності

Подібно до кешування даних, фрагмент вмісту у кеші також може мати залежності. Наприклад, вміст поста, що відображається, залежить від того, чи був він змінений.

Для визначення залежності, встановіть опцію [[yii\widgets\FragmentCache::dependency|dependency]], яка може бути або обʼєктом [[yii\caching\Dependency]] або масивом налаштувань для створення обʼєкта залежностей. Наступний код визначає, що вміст фрагмента залежить від зміни значення стовпця updated_at:

$dependency = [
    'class' => 'yii\caching\DbDependency',
    'sql' => 'SELECT MAX(updated_at) FROM post',
];

if ($this->beginCache($id, ['dependency' => $dependency])) {

    // ... тут створюємо зміст ...

    $this->endCache();
}

Варіації

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

Щоб вказати варіації кешу, встановіть опцію [[yii\widgets\FragmentCache::variations|variations]], яка повинна бути масивом скалярних значень, кожне з яких представляє певний коефіцієнт варіації. Наприклад, щоб кешувати вміст у залежності від мови додатка, ви можете використовувати наступний код:

if ($this->beginCache($id, ['variations' => [Yii::$app->language]])) {

    // ... тут створюємо зміст ...

    $this->endCache();
}

Перемикання кешування

Іноді, ви можете захотіти увімкнути кешування фрагмента тільки за певних умов. Наприклад, для сторінки, яка відображає форму, ви хочете кешувати тільки форму при її початковому запиті (через GET-запит). Будь-яке подальше відображення (через POST-запит) форми не повинне кешуватися, тому що форма може містити дані, що ввів користувач. Щоб зробити це, ви можете встановити опцію [[yii\widgets\FragmentCache::enabled|enabled]] наступним чином:

if ($this->beginCache($id, ['enabled' => Yii::$app->request->isGet])) {

    // ... тут створюємо зміст ...

    $this->endCache();
}

Вкладене кешування

Кешування фрагментів може бути вкладеним. Тобто, кешований фрагмент може бути укладений в інший фрагмент, що також кешується. Наприклад, коментарі кешируются у внутрішньому фрагменті кешу, і вони ж кешуються разом із вмістом поста у зовнішньому фрагменті кеша. Наступний код показує, як два кеша фрагментів можуть бути вкладеними:

if ($this->beginCache($id1)) {

    // ...логіка створення контента...

    if ($this->beginCache($id2, $options2)) {

        // ...логіка створення контента...

        $this->endCache();
    }

    // ...логіка створення контента...

    $this->endCache();
}

Для вкладених кешів можут бути встановлені різні опції кешування. Наприклад, внутрішні кеші і зовнішні кеші можуть використовувати різні значення тривалості кеша. Навіть коли дані зовнішнього кеша вже є недійсними, внутрішній кеш все ще може містити актуальний фрагмент. Тим не менш, це не є вірним у зворотньому напрямку. Якщо зовнішній кеш є дійсним, то він буде продовжувати віддавати кешовану копію, навіть якщо внутрішній кеш є недійсним. Таким чином, ви повинні бути обережні у визначенні тривалості або залежностей вкладених кешей, в іншому випадку застарілі внутрішні фрагменти можуть зберігатися в зовнішньому фрагменті.

Динамічний зміст

При використанні кешування фрагментів, ви можете зіткнутися із ситуацією, коли великий фрагмент змісту є відносно статичним, за винятком одного або декількох місць. Наприклад, заголовок сторінки може відображатися у головному меню разом з імʼям поточного користувача. Інша проблема в тому, що закешований зміст може містити код PHP, який повинен виконуватися при кожному запиті (наприклад, код для реєстрації пакету ресурсів). Обидві ці проблеми можуть бути вирішені за допомогою так званої функції динамічного змісту.

Динамічний зміст означає фрагмент виведення, який не повинен кешуватися, навіть якщо він укладений у кешування фрагментів. Для того, щоб зробити зміст динамічним постійно, він повинен бути створений за допомогою деякого PHP коду для кожного запиту, навіть якщо зміст віддаєтся із кеша.

Ви можете викликати [[yii\base\View::renderDynamic()]] в кеші фрагмента для вставки динамічного контенту у потрібне місце, як у прикладі нижче:

if ($this->beginCache($id1)) {

    // ...логіка створення контента...

    echo $this->renderDynamic('return Yii::$app->user->identity->name;');

    // ...логіка створення контента...

    $this->endCache();
}

Метод [[yii\base\View::renderDynamic()|renderDynamic()]] бере деяку частину коду PHP в якості параметра. Значення, що повертається від коду PHP, трактується як динамічний зміст. Цей код PHP буде виконуватися при кожному запиті, незалежно від того, чи віддається фрагмент із кешу або ні.