Кешування фрагментів ==================== Кешування фрагментів відноситься до кешування фрагментів веб-сторінки. Наприклад, якщо сторінка відображає в таблиці сумарні річні продажі, ви можете зберегти цю таблицю в кеші з метою економії часу, необхідного для створення таблиці при кожному запиті. Кешування фрагментів засноване на [кешуванні даних](caching-data.md). Для кешування фрагментів використовуйте наступний код у [представленні](structure-views.md): ```php 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()]] згенерований вміст буде записаний до кешу. Подібно до [кешування даних](caching-data.md), для кешування фрагментів необхідний унікальний ідентифікатор для визначення кешувального фрагмента. ## Параметри кешування Ви можете вказати додаткові параметри про кешуванні фрагментів, передавши масив опцій в якості другого параметра метода [[yii\base\View::beginCache()|beginCache()]]. За лаштунками, цей масив параметрів буде використано для налаштування віджета [[yii\widgets\FragmentCache]], який реалізує фактичну функціональність кешування фрагментів. ### Тривалість Мабуть найбільш часто використовуваною опцією кешування фрагмента є [[yii\widgets\FragmentCache::duration|duration]]. Вона визначає на скільки секунд вміст може залишатися дійсним у кеші. Код нижче кешує фрагмент не більше, ніж на одну: ```php if ($this->beginCache($id, ['duration' => 3600])) { // ... тут створюємо вміст ... $this->endCache(); } ``` Якщо опцію тривалості не задано, то вона прийме значенне за замовчування (60), що означає, що вміст в кеші стане недійсним через 60 секунд. ### Залежності Подібно до [кешування даних](caching-data.md#cache-dependencies), фрагмент вмісту у кеші також може мати залежності. Наприклад, вміст поста, що відображається, залежить від того, чи був він змінений. Для визначення залежності, встановіть опцію [[yii\widgets\FragmentCache::dependency|dependency]], яка може бути або обʼєктом [[yii\caching\Dependency]] або масивом налаштувань для створення обʼєкта залежностей. Наступний код визначає, що вміст фрагмента залежить від зміни значення стовпця `updated_at`: ```php $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]], яка повинна бути масивом скалярних значень, кожне з яких представляє певний коефіцієнт варіації. Наприклад, щоб кешувати вміст у залежності від мови додатка, ви можете використовувати наступний код: ```php if ($this->beginCache($id, ['variations' => [Yii::$app->language]])) { // ... тут створюємо вміст ... $this->endCache(); } ``` ### Перемикання кешування Іноді, ви можете захотіти увімкнути кешування фрагмента тільки за певних умов. Наприклад, для сторінки, яка відображає форму, ви хочете кешувати тільки форму при її початковому запиті (через GET-запит). Будь-яке подальше відображення (через POST-запит) форми не повинне кешуватися, тому що форма може містити дані, що ввів користувач. Щоб зробити це, ви можете встановити опцію [[yii\widgets\FragmentCache::enabled|enabled]] наступним чином: ```php if ($this->beginCache($id, ['enabled' => Yii::$app->request->isGet])) { // ... тут створюємо вміст ... $this->endCache(); } ``` ## Вкладене кешування Кешування фрагментів може бути вкладеним. Тобто, кешований фрагмент може бути укладений в інший фрагмент, що також кешується. Наприклад, коментарі кешируются у внутрішньому фрагменті кешу, і вони ж кешуються разом із вмістом поста у зовнішньому фрагменті кеша. Наступний код показує, як два кеша фрагментів можуть бути вкладеними: ```php if ($this->beginCache($id1)) { // ...логіка створення контента... if ($this->beginCache($id2, $options2)) { // ...логіка створення контента... $this->endCache(); } // ...логіка створення контента... $this->endCache(); } ``` Для вкладених кешів можут бути встановлені різні опції кешування. Наприклад, внутрішні кеші і зовнішні кеші можуть використовувати різні значення тривалості кеша. Навіть коли дані зовнішнього кеша вже є недійсними, внутрішній кеш все ще може містити актуальний фрагмент. Тим не менш, це не є вірним у зворотньому напрямку. Якщо зовнішній кеш є дійсним, то він буде продовжувати віддавати кешовану копію, навіть якщо внутрішній кеш є недійсним. Таким чином, ви повинні бути обережні у визначенні тривалості або залежностей вкладених кешей, в іншому випадку застарілі внутрішні фрагменти можуть зберігатися в зовнішньому фрагменті. ## Динамічний вміст При використанні кешування фрагментів, ви можете зіткнутися із ситуацією, коли великий фрагмент вмісту є відносно статичним, за винятком одного або декількох місць. Наприклад, заголовок сторінки може відображатися у головному меню разом з імʼям поточного користувача. Інша проблема в тому, що закешований вміст може містити код PHP, який повинен виконуватися при кожному запиті (наприклад, код для реєстрації колекції ресурсів). Обидві ці проблеми можуть бути вирішені за допомогою так званої функції *динамічного вмісту*. Динамічний вміст означає фрагмент виведення, який не повинен кешуватися, навіть якщо він укладений у кешування фрагментів. Для того, щоб зробити вміст динамічним постійно, він повинен бути створений за допомогою деякого коду PHP для кожного запиту, навіть якщо вміст віддаєтся із кеша. Ви можете викликати [[yii\base\View::renderDynamic()]] в кеші фрагмента для вставки динамічного контенту у потрібне місце, як у прикладі нижче: ```php if ($this->beginCache($id1)) { // ...логіка створення контента... echo $this->renderDynamic('return Yii::$app->user->identity->name;'); // ...логіка створення контента... $this->endCache(); } ``` Метод [[yii\base\View::renderDynamic()|renderDynamic()]] бере деяку частину коду PHP в якості параметра. Значення, що повертається від коду PHP, трактується як динамічний вміст. Цей код PHP буде виконуватися при кожному запиті, незалежно від того, чи віддається фрагмент із кешу або ні.