Объектно-ориентированный простой компонент в 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 дней гарантии