Свой модуль в 1С-Битрикс — это способ упаковать бизнес-логику, ORM-таблицы, компоненты и обработчики событий в единую переносимую единицу с установщиком. Правильно оформленный модуль ставится и удаляется одной кнопкой, не мусорит в чужом коде и переживает обновления ядра.
Зачем выносить логику в модуль
Мелкие правки живут в init.php, но по мере роста проекта это превращается в свалку. Модуль решает несколько задач сразу:
- Инкапсуляция — код, таблицы и настройки в одном месте с чётким namespace;
- Установка/удаление — установщик создаёт таблицы, регистрирует события и агентов, а деинсталлятор чисто всё убирает;
- Переносимость — модуль ставится на другой проект как есть;
- Обновляемость — версионирование и механизм обновлений через
updater.
vendor.module, например b2bsite.exchange. Префикс вендора обязателен для сторонних модулей, чтобы не пересечься с системными (main, iblock, sale).Структура каталогов
Модуль лежит в /local/modules/vendor.module/ (предпочтительно) или в /bitrix/modules/. Минимальный скелет:
/local/modules/b2bsite.exchange/
├── install/index.php // класс установщика
├── install/version.php // версия и дата
├── install/db/ // SQL при установке (опц.)
├── lib/ // PSR-классы, ORM-таблицы
├── lang/ru/ // языковые файлы
├── options.php // страница настроек (опц.)
└── include.php // подключается при includeModule
| Файл | Назначение |
|---|---|
install/index.php | DoInstall / DoUninstall |
install/version.php | массив с VERSION и VERSION_DATE |
include.php | константы, регистрация автозагрузки |
lib/ | классы под namespace модуля |
Файл версии
Без корректного install/version.php модуль не появится в списке. Формат строгий:
<?php
$arModuleVersion = [
'VERSION' => '1.0.0',
'VERSION_DATE' => '2026-07-16 12:00:00',
];
Версия используется механизмом обновлений: при выпуске новой версии Битрикс сравнивает её с установленной и применяет патчи из системы обновлений. Дату держите в актуальном состоянии — по ней сортируется история.
Класс установщика
Ядро установщика — класс в install/index.php, наследующий поведение от CModule. Имя класса — идентификатор модуля с заменой точки на подчёркивание.
Class b2bsite_exchange extends CModule
{
public $MODULE_ID = 'b2bsite.exchange';
public $MODULE_VERSION;
public $MODULE_NAME = 'Модуль обмена B2Bsite';
public function __construct() {
$arVersion = [];
include __DIR__ . '/version.php';
$this->MODULE_VERSION = $arVersion['VERSION'];
$this->MODULE_VERSION_DATE = $arVersion['VERSION_DATE'];
}
public function DoInstall() {
\Bitrix\Main\ModuleManager::registerModule($this->MODULE_ID);
$this->installDB();
$this->installEvents();
}
public function DoUninstall() {
$this->uninstallEvents();
\Bitrix\Main\ModuleManager::unRegisterModule($this->MODULE_ID);
}
}
Регистрация модуля через ModuleManager::registerModule() добавляет запись в b_module — именно она делает модуль «установленным» для Loader::includeModule().
Namespace и автозагрузка
Современные модули не используют require вручную — классы автоматически загружаются по namespace. Регистрация автозагрузки идёт в include.php:
\Bitrix\Main\Loader::registerAutoLoadClasses(
'b2bsite.exchange',
[
'B2bsite\Exchange\ProfileTable' => 'lib/profiletable.php',
'B2bsite\Exchange\Runner' => 'lib/runner.php',
]
);
Битрикс поддерживает и соглашение по путям: класс B2bsite\Exchange\ProfileTable ищется в lib/profiletable.php (namespace → каталоги, имя класса в нижнем регистре → файл). При строгом следовании конвенции явная регистрация не нужна.
B2bsite\Exchange, тогда как идентификатор модуля — в нижнем регистре: b2bsite.exchange. Их важно не путать.Своя ORM-таблица
Данные модуля хранят в собственных таблицах через D7-ORM. Класс таблицы наследуется от \Bitrix\Main\ORM\Data\DataManager:
namespace B2bsite\Exchange;
use Bitrix\Main\ORM\Data\DataManager;
use Bitrix\Main\ORM\Fields;
class ProfileTable extends DataManager {
public static function getTableName() { return 'b2bsite_exchange_profile'; }
public static function getMap() {
return [
new Fields\IntegerField('ID', ['primary' => true, 'autocomplete' => true]),
new Fields\StringField('NAME'),
new Fields\DatetimeField('CREATED_AT'),
];
}
}
Создать таблицу в БД из установщика можно вызовом ProfileTable::getEntity()->createDbTable(). Так схема живёт рядом с кодом, а не в оторванном SQL-дампе.
Регистрация событий модуля
Обработчики событий регистрируют в установщике постоянно (через EventManager::registerEventHandler()), а не в init.php — тогда они привязаны к жизни модуля и снимаются при удалении.
$em = \Bitrix\Main\EventManager::getInstance();
$em->registerEventHandler(
'iblock', 'OnAfterIBlockElementAdd',
$this->MODULE_ID,
'B2bsite\Exchange\Runner', 'onElementAdd'
);
Запись попадает в b_module_to_module и переживает перезагрузки. В DoUninstall() симметрично вызывайте unRegisterEventHandler() с теми же параметрами.
Итог
Свой модуль Битрикс — это структура из установщика (install/index.php + version.php), автозагрузки классов по namespace, ORM-таблиц через DataManager и постоянно зарегистрированных событий. ModuleManager::registerModule() делает его установленным, а Loader::includeModule() — подключаемым. Такой код изолирован, переносим и корректно удаляется.
Когда модуль превращается в узел обмена с 1С, ERP или маркетплейсами, важны продуманная архитектура, версионирование и обновляемость. Мы в B2Bsite разрабатываем собственные модули под задачи клиента — от универсального импортёра до сложной интеграционной логики с админ-интерфейсом.
Частые вопросы
Куда класть свой модуль — в /local или /bitrix?
Предпочтительно в /local/modules/vendor.module/. Каталог /local не затирается при обновлениях ядра, поэтому кастомный код там в безопасности. /bitrix/modules используют системные и marketplace-модули.
Как назвать идентификатор модуля?
В формате vendor.module, например b2bsite.exchange. Префикс вендора обязателен, чтобы не пересечься с системными модулями (main, iblock, sale) и чужими решениями.
Почему модуль не появляется в списке для установки?
Чаще всего некорректен install/version.php или имя класса установщика не совпадает с идентификатором (точка заменяется на подчёркивание). Проверьте наличие $arModuleVersion и имя класса вида vendor_module.
Чем namespace модуля отличается от его идентификатора?
Идентификатор пишется в нижнем регистре с точкой (b2bsite.exchange) и используется в Loader и установщике. Namespace — с заглавными сегментами через слэш (B2bsite\Exchange) и применяется в PHP-классах.
Как автоматически загружать классы модуля?
Зарегистрируйте их через Loader::registerAutoLoadClasses() в include.php либо следуйте конвенции путей: класс B2bsite\Exchange\ProfileTable ищется в lib/profiletable.php. Ручной require не нужен.
Где создавать таблицы модуля?
В методе DoInstall установщика — через ProfileTable::getEntity()->createDbTable() для ORM-сущности или SQL-скриптом. В DoUninstall симметрично удаляйте таблицы, если данные не нужно сохранять.
Почему события лучше регистрировать в установщике, а не в init.php?
registerEventHandler в DoInstall привязывает обработчики к жизни модуля: они попадают в b_module_to_module и снимаются при удалении. Регистрация в init.php живёт отдельно и легко теряется.
Как обновлять модуль после установки?
Через механизм обновлений Битрикс: повышаете VERSION в version.php и добавляете скрипты обновления. Ядро сравнивает версии и применяет патчи, что позволяет менять схему без переустановки.
Поможем с настройкой и поддержкой Для разработчиков
Поможем с настройкой, доработкой и поддержкой Для разработчиков.