1С Битрикс · 6 мин чтения

Создание компонента Битрикс: с чего начать разработку

Создание компонента Битрикс - задача, с которой рано или поздно сталкивается каждый, кто разрабатывает на этой CMS дольше пары месяцев. Стандартные news.list, catalog.section и bitrix.include закрывают большую часть типовых блоков, но как только в макете появляется вывод из двух инфоблоков сразу, интеграция с внешним API или логика, завязанная на права пользователя, - начинается написание своего кода. Ниже - порядок действий, который использую на практике: с чего начинать структуру файлов, как не потерять кеш и на чём чаще всего спотыкаются те, кто делает первый компонент.

Когда писать свой компонент, а когда хватит стандартного

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

Ситуация Хватит стандартного Нужен свой
Вывод списка новостей или товаров без нестандартной выборки да нет
Объединение данных из двух и более инфоблоков в один вывод нет да
Интеграция с внешним сервисом - СДЭК, эквайринг Т‑Банка, CRM нет да
Логика, зависящая от группы пользователя или сессии частично да
Один и тот же блок нужен на 5+ страницах с разными настройками копипаст параметров плохо масштабируется да, через параметры компонента

Если по строке «нужен свой» набирается два пункта и больше - время открывать /local/components/. Когда таких задач становится много и разбираться с ядром компонента некогда, обычно проще отдать разработку кастомного компонента на Битриксе на сторону, чем тратить неделю на чтение исходников ядра ради одной интеграции.

Из чего состоит компонент - минимальный набор файлов

Компонент - это не один файл, а папка с обязательной структурой. Битрикс ищет её по пути /местоположение/пространство_имён/имя_компонента/ и ждёт внутри конкретный набор:

  • .description.php - имя и описание компонента для визуального редактора, без него компонент не появится в списке при добавлении на страницу через админку;
  • .parameters.php - массив параметров, которые видит редактор при настройке компонента;
  • component.php - логика: выборка данных, обработка параметров, запись в $arResult;
  • templates/.default/template.php - вывод HTML на основе $arResult, минимум один шаблон обязателен;
  • templates/.default/style.css и script.js - по необходимости, шаблон сайта подключит их сам;
  • lang/ru/component.php и языковой файл шаблона - если в коде есть текстовые константы.

Для публичных компонентов, которые попадут в несколько проектов, вместо component.php завожу class.php с классом-наследником CBitrixComponent - так удобнее переиспользовать методы и тестировать логику отдельно от вывода. Для разовой задачи под конкретный сайт хватает обычного component.php - усложнять без причины смысла нет.

Пошаговое создание компонента 1С-Битрикс

Параметры в .parameters.php

Начинаю всегда с параметров - они задают контракт компонента: какие данные принимает вход и что редактор сможет менять без правки кода.

$arComponentParameters = array(
    'PARAMETERS' => array(
        'IBLOCK_ID' => array(
            'PARENT' => 'BASE',
            'NAME' => 'ID инфоблока',
            'TYPE' => 'STRING',
        ),
        'CACHE_TIME' => array(
            'PARENT' => 'CACHE_SETTINGS',
            'NAME' => 'Время кеширования (сек.)',
            'TYPE' => 'STRING',
            'DEFAULT' => 3600,
        ),
    ),
);

PARENT со значением BASE или CACHE_SETTINGS - группы, по которым Битрикс раскладывает параметры на вкладках редактора. Свои группы можно добавить через блок GROUPS, если параметров больше десяти и они логически разные.

Логика в component.php

В component.php - весь код, который трогает базу или внешний API. Правило простое: шаблон не должен знать, откуда взялись данные, а component.php не должен знать, как они отрисуются. Нарушение этого правила - причина половины багов, когда через полгода меняешь шаблон и заодно ломаешь выборку, потому что логика и вывод были перемешаны в одном файле.

if ($this->StartResultCache()) {
    $arResult['ITEMS'] = getItemsFromIblock($arParams['IBLOCK_ID']);

    if (empty($arResult['ITEMS'])) {
        $this->AbortResultCache();
    } else {
        $this->SetResultCacheKeys(array('ITEMS'));
    }

    $this->IncludeComponentTemplate();
}

StartResultCache проверяет кеш и сразу создаёт его, если раньше он не существовал - внутри условия пишется весь дорогой код: запросы к базе, обращения к внешнему API, тяжёлые вычисления.

Шаблон и вывод

template.php получает готовый $arResult и просто печатает HTML. Никаких SELECT и cURL внутри шаблона - если для вывода не хватает данных, значит их не докрутили в component.php, а не в шаблоне на скорую руку.

Бесплатный материал

🎁 Полезный скрипт в подарок

Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.

Без спама. Отписка в 1 клик.

Кэширование - где компонент теряет скорость

Собственный кеш - главная причина, по которой самодельные компоненты либо жрут базу на каждый хит, либо показывают данные недельной давности. StartResultCache кеширует результат на диске или в memcached на время из CACHE_TIME, но если в выборке участвуют инфоблоки, нужна ещё подписка на управляемый кеш - иначе после смены цены товара в каталоге старое значение провисит в кеше до истечения TTL, а это может быть и сутки.

Для инфоблоков подписка выглядит так: SetResultCacheKeys плюс регистрация тега через модуль iblock - Битрикс сам сбросит кеш конкретного компонента при изменении элемента, к которому тег привязан. Без этого шага на интернет-магазине с частым обновлением остатков через обмен с 1С компонент будет отдавать неактуальные цифры, и разбираться с этим придётся не мне, а саппорту клиента через месяц после сдачи проекта.

Типичные ошибки при написании своего компонента

  • Логика и вывод в одном файле - компонент невозможно ни кешировать частично, ни переиспользовать шаблон под другой дизайн;
  • Отсутствие проверки входных параметров - $arParams[‘IBLOCK_ID’] без intval() или htmlspecialcharsbx() открывает дорогу к некорректным запросам, если параметр приходит из GET;
  • Забытый $this->AbortResultCache() при пустой выборке - Битрикс закэширует пустой результат и будет отдавать его до истечения TTL, даже когда данные уже появились;
  • Копирование чужого компонента без замены пространства имён в CLASS и в путях - на проекте с несколькими похожими компонентами это приводит к конфликту имён классов и белому экрану;
  • Компонент без .description.php - для работы через include это не критично, но он не появится в визуальном редакторе, и вёрстальщик потом полдня ищет, почему блок не добавляется через админку.

Где размещать компонент и как его подключать

Свои компоненты кладу в /local/components/, а не в /bitrix/components/ - второй каталог перезатирается при обновлении ядра и модулей из маркетплейса, и терять код при апдейте не хочется никому. Подключение - через стандартный вызов:

$APPLICATION->IncludeComponent(
    "vendor:component.name",
    ".default",
    array(
        "IBLOCK_ID" => 12,
        "CACHE_TIME" => 3600,
    )
);

Пространство имён vendor через двоеточие - не формальность, а защита от конфликтов, если на проекте когда-нибудь окажется модуль с похожим названием компонента от другого разработчика или из маркетплейса.

Перед сдачей компонента проверяю три вещи: работает ли он при пустой выборке и не падает ли белым экраном, сбрасывается ли кеш при изменении данных и не тянет ли лишние SQL-запросы - смотрю через встроенный монитор производительности в панели администратора, вкладку «SQL-запросы».

Разобраться перед стартом

Консультация

от 3 000 ₽

Подробнее →

Частые вопросы

Сколько времени занимает написание простого компонента?

Вывод списка из одного инфоблока с базовой фильтрацией и своим шаблоном - обычно 2-4 часа вместе с версткой. Интеграция с внешним API вроде калькулятора СДЭК или эквайринга занимает уже день-два, потому что добавляется обработка сетевых ошибок и логирование.

Использовать старый API CIBlockElement или классы D7 (Bitrix\Main)?

На новых проектах беру D7 - ORM даёт готовую валидацию, события и более читаемые запросы через query builder. Старый API оставляю только когда компонент дорабатывает существующий код на CIBlockElement - переписывать рабочую часть ради стиля смысла не вижу.

Чем компонент отличается от модуля?

Компонент - это единица вывода с логикой и шаблоном, привязанная к конкретной странице или блоку. Модуль - набор классов, обработчиков событий и таблиц в базе, который может вообще не иметь визуального представления. Часто в одном модуле лежит десяток компонентов, которые пользуются его классами.

Обязательно ли делать .description.php и .parameters.php?

.description.php нужен, если компонент должен добавляться через визуальный редактор страницы - без него подключить получится только руками через include в коде шаблона. .parameters.php обязателен, если хотя бы один параметр планируется менять без правки PHP - для совсем служебного компонента, который вызывается один раз с фиксированными аргументами, можно обойтись без него, но это скорее исключение, чем практика.

Есть задача?

Обсудим в мессенджере

Расскажите, что нужно сделать — отвечу в течение 4 часов в рабочее время. Первая консультация бесплатно.

Самозанятый Калинкин Н. А. · работаю с физлицами и юрлицами

Продолжая пользование настоящим сайтом Вы выражаете своё согласие на обработку Ваших персональных данных (файлов куки) с использованием Yandex.Metrika.
Понятно