Свой компонент нужен, когда типовые не подходят: собственная выборка, нестандартная логика, интеграция с внешними данными. Правильно оформленный компонент 2.0 легко кэшируется, настраивается параметрами и переносится между проектами.
Когда стоит писать свой компонент
Прежде чем создавать компонент, стоит убедиться, что задачу не решает типовой из bitrix:* с кастомным шаблоном. Собственный компонент оправдан, когда:
- нужна нетривиальная выборка или агрегация данных из нескольких источников;
- требуется интеграция с внешним API или highload-таблицами;
- логика должна переиспользоваться на многих страницах с единой точкой поддержки;
- вывод нужно кэшировать по собственному ключу.
/local/components/ в своём пространстве имён, например partner:catalog.widget — так они не затрутся обновлением и не конфликтуют со стандартными.Минимальная структура компонента
Создадим компонент /local/components/partner/catalog.widget/. Минимальный набор файлов:
class.php— класс компонента, наследникCBitrixComponent;component.php— точка входа (может просто вызывать класс);.description.php— имя и раздел в дереве компонентов;.parameters.php— описание настраиваемых параметров;templates/.default/template.php— шаблон вывода.
Файл .description.php задаёт метаданные:
$arComponentDescription = array('NAME' => 'Виджет каталога', 'DESCRIPTION' => 'Выводит подборку товаров', 'PATH' => array('ID' => 'partner', 'NAME' => 'Наши компоненты'));
Класс компонента и executeComponent
Основная логика живёт в классе. Ключевой метод — executeComponent(), вызываемый ядром при выполнении компонента.
class CatalogWidgetComponent extends CBitrixComponent { public function executeComponent() { if ($this->startResultCache()) { $this->arResult['ITEMS'] = $this->getItems(); $this->includeComponentTemplate(); } }}
Здесь startResultCache() проверяет кэш: если данные актуальны, тело блока пропускается и берётся готовый результат. Метод includeComponentTemplate() подключает шаблон и должен вызываться внутри блока кэширования.
Файл component.php при использовании класса становится тонкой прослойкой — фактически он только гарантирует, что ядро инициализировано, а вся логика уходит в класс. Ядро само создаёт объект вашего класса, если в class.php объявлено соответствие через CBitrixComponent::includeComponentClass() или простое наследование с корректным именем файла. Разбиение на класс полезно ещё и потому, что позволяет покрывать логику юнит-тестами и переиспользовать методы выборки в других частях проекта, не дублируя код.
Обработка входных параметров
Параметры приходят в $this->arParams. Их полезно нормализовать в методе onPrepareComponentParams(), который вызывается до executeComponent():
public function onPrepareComponentParams($arParams) { $arParams['IBLOCK_ID'] = (int)($arParams['IBLOCK_ID'] ?? 0); $arParams['COUNT'] = (int)($arParams['COUNT'] ?? 10); $arParams['CACHE_TIME'] = (int)($arParams['CACHE_TIME'] ?? 3600); return $arParams;}
Здесь приводят типы, задают значения по умолчанию и очищают потенциально опасный ввод. Это защищает от ошибок и делает поведение предсказуемым.
Выборка данных
Для товаров и элементов инфоблоков используют D7-API \Bitrix\Iblock\Elements\ElementTable или классический CIBlockElement::GetList(). Пример на D7:
use Bitrix\Iblock\Elements\ElementTable;$rows = ElementTable::getList(array( 'filter' => array('IBLOCK_ID' => $this->arParams['IBLOCK_ID'], 'ACTIVE' => 'Y'), 'select' => array('ID', 'NAME', 'PREVIEW_PICTURE'), 'limit' => $this->arParams['COUNT'],))->fetchAll();
Перед выборкой обязательно проверяйте подключение нужных модулей через \Bitrix\Main\Loader::includeModule('iblock'). Если модуль не подключён, вызовите ShowError() и корректно завершите работу, а не роняйте страницу фатальной ошибкой. Для товаров с ценами и остатками помимо инфоблока подключают модуль catalog, а сами данные удобнее получать через catalog.section или API цен, а не собирать вручную.
Кэширование и тегированный кэш
Обёртка startResultCache() / endResultCache() кэширует весь результат. Чтобы кэш сбрасывался при изменении конкретных элементов, применяют тегированное кэширование:
- включить его в настройках кэша на площадке;
- зарегистрировать теги в компоненте через менеджер тегированного кэша.
if ($this->startResultCache()) { $this->arResult['ITEMS'] = $this->getItems(); if (defined('BX_COMP_MANAGED_CACHE')) { $this->getCache()->startDataCache(); $tagged = \Bitrix\Main\Application::getInstance()->getTaggedCache(); $tagged->registerTag('iblock_id_' . $this->arParams['IBLOCK_ID']); } $this->includeComponentTemplate();}
Теперь при правке элемента инфоблока Битрикс автоматически сбросит связанный кэш.
Подключение и тестирование
Готовый компонент вызывают на странице стандартно:
$APPLICATION->IncludeComponent('partner:catalog.widget', '.default', array('IBLOCK_ID' => 5, 'COUNT' => 8));
Чек-лист проверки:
- компонент появился в визуальном редакторе в своём разделе;
- параметры из
.parameters.phpотображаются в настройках; - первый вызов создаёт файл кэша в
/bitrix/cache/; - при правке данных кэш инвалидируется;
- шаблон не содержит запросов к БД.
Полезно с самого начала предусмотреть обработку пустого результата: если выборка ничего не вернула, вызовите $this->abortResultCache(), чтобы не кэшировать пустоту, и покажите заглушку. Так компонент не будет отдавать устаревший «пустой» экран после появления данных. Для сложной логики удобно вынести отдельные шаги в приватные методы класса — checkModules(), getFilter(), getItems(), — это делает executeComponent() читаемым и упрощает поддержку.
Итог
Собственный компонент 2.0 строится вокруг класса на CBitrixComponent: параметры нормализуются в onPrepareComponentParams(), выборка и кэширование выполняются в executeComponent(), а вывод отдаётся шаблону через $arResult. Такой компонент легко настраивать, кэшировать по тегам и переносить между проектами.
Когда требуется сложная выборка, интеграция с внешними системами или высокая нагрузка, мы проектируем и разрабатываем компоненты и API так, чтобы решение оставалось быстрым и поддерживаемым по мере роста проекта.
Частые вопросы
Обязательно ли создавать class.php?
Нет, простой компонент может работать процедурно в component.php. Но класс на CBitrixComponent удобнее для кэширования, параметров и повторного использования логики.
Куда класть свой компонент?
В каталог /local/components/ в собственном пространстве имён. Так он не затрётся при обновлении продукта и не конфликтует со стандартными компонентами.
Что делает метод onPrepareComponentParams?
Он вызывается до executeComponent и служит для нормализации входных параметров: приведения типов, значений по умолчанию и очистки ввода.
Почему нельзя делать запросы к БД в шаблоне?
Шаблон должен только выводить данные. Запросы в нём ломают кэширование и разделение логики, усложняют поддержку и снижают производительность.
Как связать сброс кэша с изменением данных?
Нужно включить тегированное кэширование и зарегистрировать теги, например iblock_id_5. Битрикс сбросит кэш при изменении связанных элементов.
Где описываются параметры компонента?
В файле .parameters.php. Он задаёт список настроек, которые появляются в визуальном редакторе и попадают в $arParams при вызове.
Как отладить компонент, если ничего не выводится?
Проверьте вызов includeComponentTemplate внутри блока кэша, содержимое $arResult через отладочный вывод и наличие шаблона .default. Часто причина в пустом фильтре выборки.
Поможем с настройкой и поддержкой Для разработчиков
Поможем с настройкой, доработкой и поддержкой Для разработчиков.