Кеширование в компонентах
В компонентах есть встроенная поддержка типичного алгоритма кеширования. Если есть валидный кеш, то метод StartResultCache()
отправляет в браузер его содержимое, заполняет $arResult
и возвращает false
. Если нет валидного кеша, то метод возвращает true
— это значит, настало время актуализировать кеш.
Кеширование $arResult и html-кода
В большинстве стандартных компонентов битрикс используется одновременно кеширование массива $arResult
и html-кода:
<?php
// время кеширования
if (!isset($arParams['CACHE_TIME'])) {
$arParams['CACHE_TIME'] = 3600;
} else {
$arParams['CACHE_TIME'] = intval($arParams['CACHE_TIME']);
}
// идентификатор элемента инфоблока
$arParams['ELEMENT_ID'] = empty($arParams['ELEMENT_ID']) ? 0 : intval($arParams['ELEMENT_ID']);
// если нет валидного кеша — получаем данные из БД
if ($this->StartResultCache()) {
// если модуль инфоблоки не подключен
if (! \Bitrix\Main\Loader::includeModule('iblock')) {
// отменяем кеширование
$this->AbortResultCache();
// генерируем предупреждение
ShowError('Модуль «Информационные блоки» не установлен');
return;
}
// если элемент задан
if ($arParams['ELEMENT_ID']) {
// выполняем запрос к базе данных
$rsElement = CIBlockElement::GetList(
array(), // сортировка
$arFilter, // фильтр
false, // группировка
false, // постраничная навигация
$arSelect // поля
);
// добавляем в массив arResult дополнительные элементы, которые могут потребоваться в шаблоне
if ($arResult = $rsElement->GetNext()) {
}
}
// данные получены успешно
if (isset($arResult['ID'])) {
// ключи $arResult, перечисленные при вызове этого метода, будут доступны в component_epilog.php и ниже по коду
$this->SetResultCacheKeys(
array(
'ID',
'NAME'
)
);
// подключаем шаблон и сохраняем кеш
$this->IncludeComponentTemplate();
}
// если что-то пошло не так
else {
$this->AbortResultCache();
\Bitrix\Iblock\Component\Tools::process404(
'Страница не найдена',
true,
true
);
}
}
// кэш не затронет весь код ниже, он будут выполняться на каждом хите, но здесь работаем уже с другим $arResult — будут доступны только те ключи массива, которые перечислены в вызове SetResultCacheKeys()
if (isset($arResult['ID'])) {
// счетчик просмотров элемента
CIBlockElement::CounterInc($arResult['ID']);
// устанавливаем заголовок страницы
$APPLICATION->SetTitle($arResult['NAME']);
}
Метод поддержки внутреннего кеширования компонента StartResultCache
. Возвращает true
в случае, если кеш недействителен, или false
в противном случае.
Если кеш действителен, метод отправляет на экран его содержимое, заполняет $arResult
и возвращает false
. Если кеш недействителен, метод возвращает true
, кеширование завершается и кеш сохраняется при вызове методов сразу после подключения шаблона компонента:
CBitrixComponent::IncludeComponentTemplate()
CBitrixComponent::ShowComponentTemplate()
bool CBitrixComponent::StartResultCache(
int cacheTime,
string additionalCacheID,
string cachePath
)
Параметры:
cacheTime
время кеширования в секундах. Если этот параметр равенfalse
, то время кеширования берется из входного параметра$arParams['CACHE_TIME']
. НеобязательныйadditionalCacheID
кеш зависит от текущего сайта (SITE_ID
), имени компонента, имени шаблона, входных параметров$arParams
. Если кеш должен зависеть от каких-либо дополнительных параметров, то их необходимо передать сюда в виде строки. По умолчанию параметр равенfalse
, т.е. кеш зависит только от текущего сайтаSITE_ID
, имени компонента, имени шаблона и входных параметров$arParams
. НеобязательныйcachePath
путь к файлу кеша относительно папки кешей. Необязательный
Кеширование только $arResult
При написании собственных компонентов кеширование html-кода не всегда удобно — иногда бывает нужно в шаблоне выполнять какой-то код на каждом хите. В этом случае можно кешировать только $arResult
:
<?php
// если нет валидного кеша — получаем данные из БД
if ($this->StartResultCache()) {
// если модуль инфоблоки не подключен
if (! \Bitrix\Main\Loader::includeModule('iblock')) {
// отменяем кеширование
$this->AbortResultCache();
// генерируем предупреждение
ShowError('Модуль «Информационные блоки» не установлен');
return;
}
//************************//
// Получаем данные из БД //
//************************//
// сохраняем полученные данные в кеш
$this->EndResultCache();
}
// подключаем темплейтс
$this->IncludeComponentTemplate();
Обратите внимание — подключение шаблона производится вне блока кеширования, а его место занимает EndResultCache()
.
Файл component_epilog.php
Файл component_epilog.php
подключается после файла шаблона template.php
и никогда не кешируется, т.е. он отработает независимо от того, был показан только что созданный html-код или вывод из кеша. Соответственно, можно использовать этот файл для выполнения каких-то действий на каждом хите — например, выводить html-код выше на странице, используя отложенные функции.
Отложенные функции — технология, позволяющая задавать заголовок страницы, пункты навигационной цепочки, CSS стили, дополнительные кнопки в панель управления, мета-теги и т.п. с помощью функций, используемых непосредственно в теле страницы. Соответствующие результаты работы этих функций выводятся в прологе, то есть выше по коду, чем они были заданы. Технология была создана в первую очередь для использования в компонентах, которые, как правило, выводятся в теле страницы, но при этом внутри них
могут быть заданы заголовок страницы, добавлен пункт в навигационную цепочку, добавлена кнопка в панель управления и так далее. Отложенные функции нельзя использовать в файлах шаблона компонента template.php
и result_modifier.php
(так как результаты их выполнения кешируются).
В нативных компонентах данные, доступные в component_epilog.php
, как правило, весьма ограничены — доступны лишь ключи $arResult
, перечисленные при вызове SetResultCacheKeys()
. Вносить свой код в компонент не имеет смысла — он может быть перезаписан при обновлении Битрикс. Можно еще скопировать компонент в свое пространство имен и вносить изменения в копию, но тогда будут недоступны обновления.
Можно расширить перечень этих ключей, не затрагивая код компонента. Для этого копируем шаблон компонента, создаем файл result_modifier.php
и добавляем в него код:
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) die();
// добавляем ключ SECTION в массив $arResult
$this->__component->SetResultCacheKeys(array('SECTION'));
Очистить кеш компонента
Если при выполнении некоторых условий нужно очистить кеш компонента (например, компонент знает, что данные изменились), то можно воспользоваться методом:
$this->ClearResultCache($additionalCacheID = false, $cachePath = false)
Виды кеширования в компоненте
В настройках каждого компонента можно выбрать тип кеширования:
A
Авто + Управляемое
кеш обновляется по истечении времени кеширования (Авто) или при изменении данных (Управляемое)Y
Кешировать
кеш обновляется по истечении времени кешированияN
Не кешировать
кеширования нет в любом случае
При выборе Авто + Управляемое
для всех компонентов, кеширование можно будет включить для всего сайта сразу. Не нужно заходить в настройки каждого компонента и выбирать Кешировать
. Соответственно, и выключить кеширование для всего сайта можно одним кликом в панели управления. Как правило, на этапе разработки автокеширование выключено, и включается перед запуском сайта.
Тип кеширования Авто + Управляемое
ничем не отличается от обычного кеширования — кеш обновляется через заданный промежуток времени, который задается в настройках и когда данные, с которыми работает компонент, изменились. Например, компонент показывает элементы инфоблока — после того, как данные инфоблока изменились — кеш теряет актуальность.
Суть управляемого кеша в том, чтобы пометить какой-то кеш каким-то тегом и иметь возможность по этому тегу очищать этот кеш.