Разработка компонентов Битрикс нужна там, где заканчиваются возможности готового каталога, инфоблоков и типовых форм заказа. На практике из десяти проектов на 1С-Битрикс: Управление сайтом восемь требуют минимум пару своих компонентов: нестандартный вывод карточек товара, форму с валидацией под конкретный CRM-процесс, интеграцию с эквайрингом Т‑Банка или расчёт доставки через СДЭК. Правки через хуки в init.php или чужой шаблон работают недолго: через полгода такой проект превращается в код, который боится любого обновления модуля. Свой компонент решает это иначе - логика живёт в отдельной папке, не трогает ядро и переживает обновления системы.
Когда типовых компонентов Битрикса не хватает
Стандартные bitrix:catalog.section, bitrix:catalog.element и bitrix:sale.order.ajax закрывают витрину и оформление заказа в базовом виде. Свой компонент нужен, когда:
- вывод карточек товара завязан на нестандартные свойства сразу из нескольких инфоблоков;
- форма заказа должна дёргать внешний API - расчёт доставки СДЭК, проверку промокода, статус оплаты через Т‑Банк - до сабмита, а не после;
- в личном кабинете нужен виджет, которого нет ни в одном модуле: график начислений бонусов, история заявок, дашборд для менеджера;
- событие Битрикса (OnSaleOrderSaved, OnAfterIBlockElementAdd) должно уходить наружу - в Telegram-бота для уведомления менеджера или в n8n для дальнейшей автоматизации.
Каждый из этих сценариев встречался мне минимум раз в проекте, и в каждом случае доработка типового компонента через override шаблона работает первые пару месяцев, а потом ломается на очередном обновлении модуля.
Из чего состоит компонент: структура файлов
Компонент в Битриксе - это папка внутри /local/components/vendor/component_name/ (не /bitrix/components/, потому что local не затирается при обновлении маркетплейса). Минимальный набор файлов выглядит так:
/local/components/kalinkindev/order.custom/
├── component.php
├── class.php
├── .parameters.php
├── templates/
│ └── .default/
│ ├── template.php
│ ├── style.css
│ └── script.js
└── lang/
└── ru/
└── component.php
component.php - точка входа, здесь подключается класс и вызывается executeComponent(). class.php содержит всю бизнес-логику: выборку данных, обращение к внешним сервисам, подготовку arResult. .parameters.php описывает параметры, которые администратор увидит в визуальном редакторе - от него зависит, сможет ли контент-менеджер сам поменять число элементов на странице без звонка разработчику. Шаблон в templates/.default/ отвечает только за вёрстку и получает уже готовые данные, без прямых запросов к базе.
D7 и CBitrixComponent: на чём строить логику
Компоненты старого типа с процедурным кодом в component.php до сих пор работают, но для чего-то сложнее вывода списка перехожу на D7: класс наследуется от CBitrixComponent, данные достаю через ORM-сущности (BitrixIblockElementTable, кастомные Entity для highload-блоков), ошибки собираю в ErrorCollection вместо разбросанных по коду ShowError().
<?php
namespace Kalinkindev\Order;
use Bitrix\Main\ErrorCollection;
class CustomOrderComponent extends \CBitrixComponent
{
private ErrorCollection $errors;
public function onPrepareComponentParams($arParams)
{
$arParams['CACHE_TIME'] = $arParams['CACHE_TIME'] ?? 3600;
return $arParams;
}
public function executeComponent()
{
$this->errors = new ErrorCollection();
if ($this->startResultCache()) {
$this->arResult['ITEMS'] = $this->getDeliveryOptions();
if (!$this->errors->isEmpty()) {
$this->abortResultCache();
}
$this->includeComponentTemplate();
}
}
}
Такой подход даёт нормальную обработку ошибок на шаблоне (arResult[‘ERRORS’] вместо ShowError() посреди вёрстки) и класс, который тестируется отдельно: логику выборки можно вызвать напрямую в phpunit-тесте, без поднятия всего движка.
Бесплатный материал
🎁 Полезный скрипт в подарок
Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.
Без спама. Отписка в 1 клик.
Интеграция с инфоблоками, highload-блоками и внешними сервисами
Свои компоненты чаще всего пишу не ради вывода контента, а для стыковки Битрикса с внешним миром:
- расчёт доставки СДЭК прямо в форме заказа: компонент дёргает API СДЭК по индексу или адресу, показывает пункты выдачи на карте и передаёт стоимость в заказ до оплаты, а не после подтверждения;
- приём оплаты через Т‑Банк с созданием платежа на этапе оформления, а не редиректом на отдельную страницу эквайринга модуля sale;
- характеристики товара из highload-блока, которые не влезают в стандартные свойства инфоблока - типичный случай для магазинов с сотнями фильтруемых параметров;
- уведомление менеджера в Telegram при смене статуса заказа через обработчик события OnSaleStatusOrderChange, который отправляет вебхук в n8n, а тот уже маршрутизирует сообщение в нужный чат.
Если проект требует сразу нескольких таких интеграций одновременно - эквайринг, доставка, CRM - обычно беру это отдельным этапом и описываю в услугах по разработке под задачу проекта, потому что тащить внешние API в типовые компоненты через хаки смысла нет: они не переживут следующее обновление модуля.
Кеширование компонентов без просадки производительности
Кастомный компонент, который на каждый хит страницы обращается к API СДЭК или Т‑Банка, за неделю кладёт прод при десятке одновременных пользователей. Кеширую то, что можно кешировать: результат запроса тарифов по индексу - на час через управляемый кеш с тегами по инфоблоку, а не через жёсткий CACHE_TIME, чтобы сброс происходил по событию OnAfterIBlockElementUpdate, а не по таймеру. Данные, которые обязаны быть актуальными в моменте - статус оплаты, остаток на складе - кешу не подлежат, но здесь нельзя гонять в цикле по одному запросу на элемент: highload-блоки и D7 ORM дают getList() с фильтром по массиву ID, и один запрос на пятьдесят элементов в разы дешевле пятидесяти запросов по одному.
Композитный кеш Битрикса (модуль composite) с кастомными компонентами дружит не всегда: если в шаблоне есть логика, завязанная на текущего пользователя - персональные бонусы, история заявок - такой блок оборачиваю в подгрузку через AJAX, иначе вся страница попадает в статический кеш с чужими данными на экране у следующего посетителя.
Тестирование и деплой своих компонентов
Обновление модулей 1С-Битрикс само по себе не трогает /local/components/, и это ровно то преимущество, ради которого свои компоненты пишут вместо правок в /bitrix/. Перед выкладкой на прод гоняю изменения на копии сайта с той же версией модулей и PHP, а не на локальном стенде с другой версией: разница между PHP 8.1 и 8.2 в деталях типизации ловит баги, которых на локали не видно.
Для параметров компонента, которые меняются между версиями (добавил новый CACHE_TYPE или переименовал параметр), пишу миграции через инструменты модуля main, чтобы у контент-менеджера в визуальном редакторе не появлялись пустые обязательные поля после обновления. Без этого шага апдейт компонента на боевом сайте с десятком настроенных экземпляров превращается в ручной обход каждой страницы.
Частые вопросы
Сколько стоит разработка кастомного компонента для Битрикс?
Зависит от объёма: доработка вывода карточек товара под нестандартные свойства инфоблока - одна оценка, интеграция с эквайрингом или СДЭК с обработкой событий и вебхуками - совсем другая, там счёт идёт на недели, а не на часы. Точка отсчёта для оценки конкретной задачи - консультация от 3 000 ₽, дальше называю сумму по ТЗ.
Можно ли дорабатывать типовой компонент вместо создания своего?
Через override шаблона - копию в /local/templates/ с изменённым template.php - да, для косметических правок вёрстки. Но если меняется логика выборки данных или добавляется обращение к внешнему API, override быстро превращается в дублирование половины component.php с патчами поверх, и на следующем обновлении модуля этот патч перестаёт совпадать со структурой оригинала. В таких случаях свой компонент с нуля выходит дешевле в поддержке, даже если разработка занимает на пару дней больше.
Переживут ли кастомные компоненты обновление 1С-Битрикс?
Если компонент лежит в /local/components/ и не переопределяет файлы ядра напрямую, обновление модулей через маркетплейс его не тронет. Ломается такое обычно не от апдейта самого Битрикса, а от смены версии PHP на хостинге или от изменений в API модуля, к которому компонент обращается, например sale - это стоит проверять на копии сайта перед переносом изменений на прод, а не после.
Нужен ли доступ к маркетплейсу 1С-Битрикс для установки своих компонентов?
Нет, свои компоненты в /local/components/ устанавливаются копированием файлов через FTP, git-деплой или систему обновлений хостинга, лицензия модуля Marketplace для этого не нужна. Доступ к маркетплейсу нужен, только если планируете публиковать компонент как отдельное решение для чужих проектов - для внутренней разработки под конкретный сайт это не требуется.