Yandex Metrika
sanches.free

Объектно-ориентированный простой компонент в Bitrix: класс-наследник и executeComponent

Канон для простого компонента

В ядре 1С‑Битрикс простой компонент подключается через component.php в каталоге компонента. Ожидаемый и поддерживаемый вариант — объявить собственный PHP-класс, который расширяет CBitrixComponent, а входную точку оформить методом executeComponent(). Оттуда вы подключаете модули, собираете $this->arResult, включаете кеш при необходимости и завершаете цикл вызовом $this->includeComponentTemplate(). Так вы остаетесь в одном объекте с готовым контрактом жизненного цикла, а платформа может применять стандартную интроспекцию, события и правила автокеша.

Минимальный каркас с D7-подключением модуля

Защиту файла через B_PROLOG_INCLUDED, псевдонимы через use и явное подключение модуля через Bitrix\Main\Loader удобно держать в начале того же класса. Имена ниже условные, чтобы пример не копировался с чужих сниппетов один в один:

<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) {
    die();
}

use Bitrix\Main\Loader;

class ShelfSpotlight extends CBitrixComponent
{
    public function executeComponent(): void
    {
        if (!Loader::includeModule('iblock')) {
            return;
        }

        $ttl = (int)($this->arParams['CACHE_TIME'] ?? 3600);
        $facetKey = [
            (int)($this->arParams['SHELF_ID'] ?? 0),
            $this->arParams['SORT_HINT'] ?? 'default',
        ];

        if ($this->startResultCache($ttl, $facetKey)) {
            $this->arResult['rows'] = $this->collectShelfRows();
            $this->setResultCacheKeys(['rows']);
            $this->includeComponentTemplate();
        }
    }

    protected function collectShelfRows(): array
    {
        return [];
    }
}

Внутрь collectShelfRows() уже кладётся ваш выбор данных: можно сочетать ORM D7 там, где она доступна для сущности, и вызовы легаси-API там, где ещё нет альтернативы.

Зачем не переносить логику в «внешний» класс

Раньше популярен был приём создать отдельный класс, в конструктор передать текущий инстанс компонента как $this из процедурной оболочки, вручную проставить ссылки на $APPLICATION, $DB, $USER и пытаться синхронно дергать startResultCache(), endResultCache() и обходиться без чёткого деления между «вычислить результат» и «отрисовать». Такой текст сложнее сопровождать, его легко сломать при двойном включении экземпляра на странице, а платформенные советы по кешированию описывают всё-таки путь через наследника CBitrixComponent. Если нужна дополнительная декомпозиция, логичнее вынести сервисы в lib/ модуля или в автозагружаемые классы локального решения и вызывать их из тела компонента, а не городить второй объект-обертку над ядром.

Кеш, повторное использование и отмена

  • Ключи и массив зависимостей для второго аргумента startResultCache() должны включать всё, что реально меняет вывод: параметры фильтра, режим AJAX, регион, флаги доступа если они влияют на разметку.
  • Если в процессе стало очевидно, что сохранять нельзя — вызывайте AbortResultCache(), как рекомендует документация платформы, вместо «тихих» расхождений между файлом на диске и фактическим HTML.
  • Для тегового сброса сочетайте поведение инфоблоковых выборок с CACHE_TYPE = A на параметрах компонента или добавляйте явные регистрации тегов рядом с участком между успешным startResultCache() и выводом шаблона — это уже ближе к практическим советам про TagCache.

Кратко

Опирайтесь на класс, наследующий CBitrixComponent, метод executeComponent() и стандартные вызовы кеширования или инвалидации внутри него — это ровняет ваш код под ожидания ядра и будущую поддержку. Громоздкие обертки над контекстом компонента оставили в истории сообществ; для новых проектов выбирайте деление на маленькие сервисы и тонкий фасад внутри компонента.

Не хотите копаться сами?

Починю за 1-3 дня. Без предоплаты — оплата по результату.

15+ лет опыта с 1С-Битрикс · Без предоплаты · 7 дней гарантии