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

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

Для використання кешування фрагментів ми викликаємо методи [CController::beginCache()|CBaseController::beginCache()] і [CController::endCache()|CBaseController::endCache()] у скрипті представлення контролера. Ці два методи є мітками початку і кінця вмісту сторінки, який має бути кешуваний. Як і в [кешуванні даних](/doc/guide/caching.data), нам потрібен ідентифікатор для визначення кешованого фрагмента.

~~~
[php]
…інший HTML-вміст…
<?php if($this->beginCache($id)) { ?>
…кешований вміст…
<?php $this->endCache(); } ?>
…інший HTML-вміст…
~~~

У коді вище, якщо метод [beginCache()|CBaseController::beginCache()] повертає false, то кешований вміст буде автоматично вставлений в дане місце, інакше, вміст всередині виразу `if` буде виконано і збережено в кеші, коли буде викликаний метод [endCache()|CBaseController::endCache()].

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

Викликаючи метод [beginCache()|CBaseController::beginCache()], ми можемо передати у якості другого параметра масив, що містить параметри кешування для управління кешуванням фрагмента. Фактично, методи [beginCache()|CBaseController::beginCache()] і [endCache()|CBaseController::endCache()] є зручною обгорткою віджету [COutputCache]. Тому, параметри кешування можуть бути початковими значеннями для будь-яких властивостей віджету [COutputCache].

### Тривалість (термін зберігання)

Напевно, найбільш часто використовуваним параметром є [duration|COutputCache::duration], який визначає, наскільки довго вміст кешу буде залишатися дійсним (валідним). Це схоже на параметр терміну дії методу [CCache::set()]. Код нижче кешує фрагмент на час не більше години:

~~~
[php]
…інший HTML-вміст…
<?php if($this->beginCache($id, array('duration'=>3600))) { ?>
…кешований вміст…
<?php $this->endCache(); } ?>
…інший HTML-вміст…
~~~

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

Починаючи з версії 1.1.8, якщо виставити duration в 0, то відповідне значення буде видалено з кешу. Якщо ж застосувати відʼємне значення duration, кеш буде відключений, але існуюче значення в ньому залишиться. До 1.1.8, як при виставленні 0, так і при використанні відʼємного значення кеш відключався без очищення значення.

### Залежності

Як і [кешування даних](/doc/guide/caching.data), кешований вміст фрагмента теж може мати залежності. Наприклад, відображення вмісту повідомлення залежить від того, змінено це повідомлення чи ні.

Для визначення залежності, ми встановлюємо параметр [dependency|COutputCache::dependency], який може бути або обʼєктом, що реалізує інтерфейс [ICacheDependency], або масивом налаштувань, який може бути використаний для генерації обʼєкта залежності. Наступний код визначає вміст фрагмента, який залежить від зміни значення стовпця `lastModified`:

~~~
[php]
…інший HTML-вміст…
<?php if($this->beginCache($id, array('dependency'=>array(
		'class'=>'system.caching.dependencies.CDbCacheDependency',
		'sql'=>'SELECT MAX(lastModified) FROM Post')))) { ?>
…кешований вміст…
<?php $this->endCache(); } ?>
…інший HTML-вміст…
~~~

### Варіації (зміни)

Кешований вміст може бути змінено відповідно до деяких параметрів. Наприклад, особистий профіль може по-різному виглядати для різних користувачів. Для кешування вмісту профілю ми б хотіли, щоб кешована копія була різною у відповідності з ідентифікатором користувача. По-суті, це означає, що ми повинні використовувати різні ідентифікатори при виклику метода [beginCache()|CBaseController::beginCache()].

Замість того, щоб запитувати у розробника різні ідентифікатори, відповідні деякій схемі, існує клас [COutputCache], який містить таку можливість. Нижче наведено перелік вбудованих варіацій:

   - [varyByRoute|COutputCache::varyByRoute]: якщо встановлено у значення true, кешований вміст буде змінюватися у відповідності з налаштуваннями [маршруту](/doc/guide/basics.controller#route). Тому, кожна комбінація запитуваного контролера і дії будуть мати різний кешований вміст;

   - [varyBySession|COutputCache::varyBySession]: якщо встановлено у значення true, кешований вміст буде змінюватися відповідно до ідентифікатора сесії. Тому, кожна користувацька сесія може бачити різний вміст і отримувати його з кешу;

   - [varyByParam|COutputCache::varyByParam]: якщо встановлено в якості масиву імен, кешований вміст буде змінюватися у відповідності з певними GET параметрами. Наприклад, якщо сторінка відображає вміст повідомлення залежно від GET-параметра `id`, ми можемо визначити [varyByParam|COutputCache::varyByParam] у вигляді масиву `array('id')` і потім кешувати вміст кожного повідомлення. Без такої варіації, ми могли б кешувати лише одне повідомлення;

   - [varyByExpression|COutputCache::varyByExpression]: якщо встановлено у якості виразу PHP, кешований вміст буде змінюватися відповідно до результату даного виразу PHP.

### Типи запитів

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

~~~
[php]
…інший HTML-вміст…
<?php if($this->beginCache($id, array('requestTypes'=>array('GET')))) { ?>
…кешований вміст…
<?php $this->endCache(); } ?>
…інший HTML-вміст…
~~~

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

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

~~~
[php]
…інший HTML-вміст…
<?php if($this->beginCache($id1)) { ?>
…зовнішній кешований вміст…
	<?php if($this->beginCache($id2)) { ?>
	…внутрішній кешований вміст…
	<?php $this->endCache(); } ?>
…зовнішній кешований вміст…
<?php $this->endCache(); } ?>
…інший HTML-вміст…
~~~

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