Автокэширование в 1с-Битрикс — сложно о простом

Автокэширование в 1с-Битрикс — хорошо развитая и довольно сложная система, позволяющая в разы уменьшить число обращений к базе данных и ускорить выполнение страниц. Понимать принципы и грамотно ее использовать должен любой успешный «битрикс-разработчик» для создания быстрых и качественных проектов. Сегодня поговорим о связи кэша и шаблона компонента.

Как работает компонент

Для начала небольшое описание составных частей среднестатистического компонента в 1с-Битрикс:

  1. component.php — файл с кодом, который формирует данные для шаблона ($arResult) и подключает его. Кроме того, может выполнять какие-либо действия после получения данных. Например, устанавливать заголовок страницы или добавлять пункты в навигационную цепочку.
  2. template.php — файл шаблона. В идеале не содерижит никакой логики, только вывод данных из $arResult. кэшируется html-вывод, т.е. PHP код из этого файла выполнится 1 раз, затем будет возвращаться html до следующего обновления кэша.
  3. result_modifier.php — файл, который подключается до template.php и может менять $arResult. кэшируется так же как и template.php
  4. component_epilog.php — файл, который подключается после template.php. Не кэшируется.

Последние 3 файла относятся к шаблону, предпочтительно редактировать именно их. Component.php в стандартных компонентах изменять нельзя, т.к. есть шанс что правки затрутся после обновления системы.

Общую схему работы компонента можно представить несколькими шагами:

  1. Проверка входных данных в component.php
  2. Проверка на наличие валидного (активного) кэша файлов result_modifier.php и template.php. Если кэш валидный, то вывод его, заполнение $arResult и переход к пункту 5.
  3. В случае невалидного кэша производятся необходимые действия для получения данных. По сути — заполняется массив $arResult
  4. Подключение файлов result_modifier.php и template.php, формирование + вывод html, а также «запоминание» этого вывода и части массива $arResult
  5. Подключение файла component_epilog.php
  6. Выполнение остального кода в component.php

Что нужно помнить

Содержимое массива $arResult на разных этапах различается. В result_modifier.php и template.php попадает массив, содержащий ВСЕ данные, которые получены на шаге 3. В файле component_epilog.php и коде компонента, который выполняется после него, доступны данные массива $arResult с ключами, которые были указаны в функции $this->SetResultCacheKeys(Array()). Вызов ее происходит в компоненте.

Например,

// component_epilog шаблона компонента news.list
// задача - вывести заголовок страницы вида "[Название инфоблока] (кол-во элементов)"
global $APPLICATION;

/*
// кусок кода из component.php, так устанавливаются ключи, которые попадут в кэш
$this->SetResultCacheKeys(array(
	"ID",
	"IBLOCK_TYPE_ID",
	"LIST_PAGE_URL",
	"NAV_CACHED_DATA",
	"NAME",
	"SECTION",
	"ELEMENTS",
));
*/

// этот код не сработает, т.к. в массиве $arResult не определен элемент с ключем "ITEMS"
if(isset($arResult["NAME"]) && isset($arResult["ITEMS"])) {
	$title = $arResult["NAME"]." (".count($arResult["ITEMS"]).")";
	$APPLICATION->SetTitle($title);
}

// правильный вариант, все нужные элемента массива присутствуют в кэше
if(isset($arResult["NAME"]) && isset($arResult["ELEMENTS"])) {
	$title = $arResult["NAME"]." (".count($arResult["ELEMENTS"]).")";
	$APPLICATION->SetTitle($title);
}

Данные, которые доступны в component_epilog.php и далее (т.е. указаны в SetResultCacheKeys) можно изменять в result_modifier.php и template.php. Будет закэшировано их новое значение.

Например,

// result_modifier шаблона компонента news.list
// задача - вывести заголовок страницы вида "[Название инфоблока] (кол-во элементов)"
// доступен весь массив $arResult и мы можем переопределить элементы, которые попадут в кэш
$arResult["NAME"] .= " (".count($arResult["ELEMENTS"]).")";
// теперь при отмеченной опции "Устанавливать заголовок страницы" компонент использует измененный $arResult["NAME"] и мы получим нужный заголовок

В result_modifier.php можно добавлять данные в кэш.

Например,

// result_modifier шаблона компонента news.list
// задача - "SEOшник со стажем" сказал сделать description вида "[Название элементов через запятую] скачать бесплатно без регистрации без смс"
$arNames = Array(); // сюда собираем названия элементов
foreach($arResult["ITEMS"] as $arItem)
	$arNames[] = $arItem["NAME"];
$arResult["DESCRIPTION"] = implode(", ", $arNames)." скачать бесплатно без регистрации без смс";
$cp = $this->__component; // объект компонента
if (is_object($cp))
   $cp->SetResultCacheKeys(array('DESCRIPTION')); // запомнить $arResult["DESCRIPTION"] в кэш
// component_epilog шаблона компонента news.list
global $APPLICATION;
// устанавливаем DESCRIPTION
if(isset($arResult["DESCRIPTION"])) {
	$APPLICATION->SetDirProperty("keywords", $arResult["DESCRIPTION"]);
}

Для полного понимания технологии кэширования обязательны к прочтению следующие материалы:
- Компоненты 2.0::кэширование в компоненте и далее по разделу
- component_epilog и шаблон компонента
- Компоненты

Если вам понравилась статья, подписывайтесь на обновления блога по rss или присоединяйтесь в twitter

Поделиться ссылкой с друзьями: