Свой компонент в Битрикс: рабочие приёмы
Собственный компонент в 1С-Битрикс нужен там, где шаблонный компонент уже не выдерживает бизнес-логику. Показываем, как разделить запросы, параметры и шаблон, добавить кеширование и не превратить решение в копию ядра.

Собственный компонент в 1С-Битрикс окупается, когда один и тот же вывод нужно использовать на нескольких страницах, кешировать отдельно и настраивать через параметры. На практике проблема начинается не с PHP-кода, а с неправильного места для логики: запросы оказываются в шаблоне, параметры жёстко зашиваются в файл, а после обновления шаблона приходится переписывать компонент.
Что именно будем собирать
Разберём компонент для вывода подборки элементов инфоблока: он принимает ID инфоблока и количество записей, получает активные элементы, передаёт их в шаблон и кеширует результат. Примеры рассчитаны на API 1С-Битрикс: Управление сайтом, используемый в ветках 24.x–25.x, с PHP-версией, поддерживаемой вашей редакцией продукта.
В статье не рассматривается создание собственного типа данных, сложная постраничная навигация и AJAX-фильтр. Это отдельные задачи: их лучше добавлять после того, как базовый компонент стабильно работает.
Компонент — это не файл с HTML. Это граница между входными параметрами, получением данных и представлением.
Компонент — переиспользуемый блок 1С-Битрикс со своим PHP-файлом, параметрами, результатом и шаблоном. Компонентный кеш[1] сохраняет результат работы блока, чтобы не выполнять запрос к базе при каждом открытии страницы.
Три способа вывести один и тот же блок
Перед разработкой стоит выбрать границу переиспользования. Не каждый вывод требует собственного компонента.
| Подход | Когда подходит | Цена решения |
|---|---|---|
| Вызов готового компонента | Логика совпадает с возможностями штатного компонента | Меньше кода, но вы ограничены его параметрами и форматом результата |
| Включаемый PHP-файл | Блок уникален для одной страницы или одного проекта | Быстрый старт, но слабее переиспользование и настройка через админку |
| Собственный компонент | Блок повторяется, имеет отдельные параметры и собственный кеш | Нужно поддерживать структуру, параметры, шаблон и совместимость API |
Если требуется только изменить HTML штатного решения, сначала проверьте возможность переопределить его шаблон в local/templates/<имя_шаблона>/components/. Копировать компонент целиком в local/components стоит только тогда, когда меняется PHP-логика, а не только разметка.
Структура собственного компонента
Для компонента с именем acme:catalog.selection создайте каталог:
local/components/acme/catalog.selection/
├── .description.php
├── .parameters.php
├── component.php
└── templates/
└── .default/
└── template.php
Папка local/components предпочтительнее bitrix/components: файлы в ядре нельзя считать безопасным местом для собственных изменений. Обновление продукта может заменить содержимое каталога bitrix.
Параметры компонента
Файл .parameters.php описывает поля, которые увидит разработчик при добавлении компонента через визуальный редактор. Для простого блока достаточно двух параметров:
<?php
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) {
die();
}
$arComponentParameters = [
"GROUPS" => [],
"PARAMETERS" => [
"IBLOCK_ID" => [
"PARENT" => "BASE",
"NAME" => "ID инфоблока",
"TYPE" => "STRING",
"DEFAULT" => "0",
],
"COUNT" => [
"PARENT" => "BASE",
"NAME" => "Количество элементов",
"TYPE" => "STRING",
"DEFAULT" => "5",
],
],
];
Значения из формы компонента всё равно нужно проверять в PHP. Параметры не считаются доверенными только потому, что их заполняет администратор.
Запрос и результат
В component.php оставьте получение данных и подготовку результата. В шаблоне не должно быть вызова CIBlockElement::GetList: иначе разметка начинает зависеть от структуры базы.
<?php
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) {
die();
}
use Bitrix\Main\Loader;
$iblockId = (int)$arParams["IBLOCK_ID"];
$elementCount = max(1, min(50, (int)$arParams["COUNT"]));
$arResult = [
"ITEMS" => [],
];
if ($iblockId <= 0 || !Loader::includeModule("iblock")) {
return;
}
$elements = CIBlockElement::GetList(
["SORT" => "ASC", "ID" => "DESC"],
[
"IBLOCK_ID" => $iblockId,
"ACTIVE" => "Y",
],
false,
["nTopCount" => $elementCount],
["ID", "IBLOCK_ID", "NAME", "DETAIL_PAGE_URL", "PREVIEW_TEXT"]
);
while ($element = $elements->GetNext()) {
$arResult["ITEMS"][] = [
"ID" => (int)$element["ID"],
"NAME" => $element["NAME"],
"URL" => $element["DETAIL_PAGE_URL"],
"PREVIEW_TEXT" => $element["PREVIEW_TEXT"],
];
}
$this->IncludeComponentTemplate();
Ограничение количества элементов в коде защищает страницу от случайного значения вроде нескольких тысяч записей. Число 50 здесь не является требованием Битрикс: это пример безопасной границы для конкретного блока, который нужно согласовать с интерфейсом проекта.
Шаблон без бизнес-логики
Файл templates/.default/template.php отвечает только за HTML. Значения, пришедшие из базы, выводите через безопасное экранирование:
<?php
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) {
die();
}
if (!$arResult["ITEMS"]) {
return;
}
?>
<section class="catalog-selection">
<ul class="catalog-selection__list">
<?php foreach ($arResult["ITEMS"] as $item): ?>
<li class="catalog-selection__item">
<a href="<?=htmlspecialcharsbx($item["URL"]) ?>">
<?=htmlspecialcharsbx($item["NAME"]) ?>
</a>
<p><?=htmlspecialcharsbx($item["PREVIEW_TEXT"]) ?></p>
</li>
<?php endforeach; ?>
</ul>
</section>
htmlspecialcharsbx — функция экранирования вывода, используемая в окружении Битрикс. Она нужна даже для данных из инфоблока: редактор или импорт могли записать туда HTML и специальные символы.
Кеш: где он помогает, а где прячет ошибку
Компонент без кеша выполняет запрос при каждом открытии страницы. Для небольшого блока это может быть приемлемо, но на странице с несколькими компонентами число запросов быстро растёт. При включении кеша важно включить в его зависимость все параметры, меняющие результат.
Минимальная схема выглядит так:
<?php
if ($this->StartResultCache(false, [$iblockId, $elementCount])) {
// Здесь выполняется запрос и собирается $arResult.
$this->IncludeComponentTemplate();
}
В рабочем компоненте вызов IncludeComponentTemplate() должен находиться внутри ветки кеширования после формирования результата. Если данные зависят от пользователя, группы, региона или других переменных, их тоже нужно учитывать в ключе либо отключить кеш для такого результата.
Частая ошибка — проверить изменение элемента в админке и решить, что компонент сломан: на странице всё ещё показывается старое значение. Сначала очистите кеш компонента или общий кеш сайта, затем повторите проверку. Для персонального вывода общий кеш без разделения по пользователю опасен: один посетитель может увидеть результат, собранный для другого.
Как подключить компонент
В PHP-шаблоне страницы компонент вызывается стандартным методом:
<?php
$APPLICATION->IncludeComponent(
"acme:catalog.selection",
"",
[
"IBLOCK_ID" => 7,
"COUNT" => 5,
"CACHE_TYPE" => "A",
"CACHE_TIME" => 36000000,
]
);
Число 7 — пример ID, а не универсальное значение: на другом проекте его нужно заменить на ID нужного инфоблока. Параметры кеша передаются стандартному механизму компонента, но фактическое поведение зависит от реализации кеширования в компоненте и настроек сайта.
После подключения проверьте три сценария: есть активные элементы, элементов нет, указан несуществующий инфоблок. Компонент не должен выдавать предупреждения PHP и не должен падать, если база вернула пустой результат.
Что обычно ломается
- «Class 'CIBlockElement' not found». Не подключён модуль «Информационные блоки» или код выполняется не в штатном окружении Битрикс. Проверьте результат
Loader::includeModule("iblock"). - Пустой список при правильном ID. Проверьте активность элементов, ID инфоблока и сайт, к которому он привязан. Условия
ACTIVE => YиIBLOCK_IDдолжны соответствовать данным проекта. - Изменения в шаблоне не видны. Очистите кеш компонента и убедитесь, что редактируете шаблон с тем же именем, который указан при подключении.
- В HTML появляются лишние символы или разметка ломается. Проверьте экранирование URL, названия и текста. Не выводите значения из базы напрямую в атрибуты и HTML.
- На странице видны данные другого пользователя. Кеширование применено к персональному результату без разделения по пользователю. Уберите такие данные из кешируемого результата или добавьте корректную зависимость.
Когда какой подход выбирать
Берите штатный компонент, если он уже умеет нужную выборку, сортировку и постраничность. Переопределяйте только шаблон, если изменяется внешний вид. Пишите собственный компонент, если один блок нужен в нескольких местах, получает собственные параметры или должен иметь отдельный кеш.
Не копируйте исходный компонент ядра без необходимости. Копия быстро расходится с обновлениями: исправление в штатном компоненте не попадёт в вашу версию автоматически. Если без копирования не обойтись, зафиксируйте версию исходника и список собственных изменений в репозитории.
Что делать дальше
Добавьте к компоненту проверку параметров и логирование только на время диагностики, затем проверьте страницу с включённым и отключённым кешем. В продакшене измеряйте время ответа страницы, число запросов к базе и размер кешируемого результата. Следующим шагом можно вынести выборку в отдельный класс или добавить постраничную навигацию, но эти изменения лучше делать после проверки реального профиля нагрузки.
[1] Компонентный кеш — сохранённый результат конкретного вызова компонента. Он не равен кешу браузера и не заменяет кеширование запросов или объектов на уровне базы данных.
Редактор изображений: Убрать лишнее, заменить фон, добавить объект, расширить кадр — на вашем изображении.
Спросить за 20 ₽Источники: Официальная документация 1С-Битрикс: CBitrixComponent, Официальная документация 1С-Битрикс: CIBlockElement::GetList
Частые вопросы
Можно ли положить свой компонент в bitrix/components?
Почему компонент работает без кеша, но показывает старые данные после включения кеша?
Что делать, если у меня другая версия Битрикс?
Нужно ли создавать класс-наследник CBitrixComponent?
Почему не вызывается шаблон после IncludeComponentTemplate?
Можно ли выполнять запрос к инфоблоку прямо в template.php?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.