Модуль уже есть в b_module, а Loader::includeModule() на странице молча вернул false. Чаще всего виноваты пустой include.php, перепутанный класс vendor_module и вызов lib/ до registerModule. Подключение в коде выглядит так: сначала проверьте, что модуль установлен, затем вызовите ядро. Если зависимость обязательна и без неё страница не должна открываться - используйте requireModule, он бросит исключение вместо тихого false.
use Bitrix\Main\Loader;
if (Loader::includeModule('mycompany.custommodule')) {
$logger = new \Mycompany\Custommodule\Service\Logger();
} else {
// модуль не установлен или ошибка в include.php
}
// жёсткая зависимость:
Loader::requireModule('mycompany.custommodule');
Ниже - пошаговый путь от пустой папки vendor.module до установленного модуля в 1С-Битрикс: Управление сайтом, который переносится между проектами и удаляется без хвостов в базе.
Модуль 1С-Битрикс: Управление сайтом - автономный пакет в /local/modules/vendor.module с установщиком install/index.php (класс vendor_module), версией, include.php и классами D7 в lib/. Подключение в коде - Bitrix\Main\Loader::includeModule('vendor.module'), который выполняет include.php и возвращает true или false. Сегодня разберите дерево папок по официальной архитектуре, соберите install-цикл и проверьте includeModule сразу после установки через админку.
Речь про коробочную CMS, не про Bitrix24. Ядро /bitrix не трогаем - кастом лежит в /local. Анатомия папок без install-цикла - в шпаргалке по структуре модулей, здесь полный цикл до uninstall.
Разберите структуру модуля Битрикс: дерево папок по docs architecture
ID модуля vendor.module совпадает с папкой. Класс в install/index.php - vendor_module (точка → подчёркивание). Канон - архитектура модулей BitrixFramework.
Дерево /local/modules/vendor.module/
vendor.module/
├── install/
│ ├── index.php - класс vendor_module extends CModule, DoInstall и DoUninstall
│ └── version.php - VERSION и VERSION_DATE
├── lib/ - классы D7, namespace Vendor\Module
├── include.php - Loader::registerAutoLoadClasses для lib/
├── lang/ru/install/index.php - тексты мастера установки
├── options.php - страница настроек в админке
└── default_option.php - значения опций по умолчанию
includeModule подключает include.php; requireModule бросает LoaderException при сбое. Делайте: сверяйте scaffold с деревом. Не делайте: не кладите модуль в /bitrix/modules.
Определите, когда нужен свой модуль, а когда хватит init.php или компонента
На практике init.php - быстрый патч на один проект. Модуль - когда логику переносят, версионируют и ставят через админку.
| Ситуация | init.php (B58) | Компонент в /local (B63) | Свой модуль |
|---|---|---|---|
| Один обработчик OnOrderAdd на staging | Да - быстрый тест | Нет | Избыточно |
| Блок на странице с шаблоном | Нет | Да - class.php + IncludeComponent | Только если компонент ставится через InstallFiles |
| События + опции в админке + lib/ | Риск хаоса в init.php | Недостаточно | Да - install/index.php и options.php |
| Перенос между dev и prod | Ручное копирование | Частично через git | Да + миграции из гайда по Sprint Migration |
Обработчики без install-цикла - AddEventHandler, вывод на странице - свой компонент. Делайте: модуль при InstallEvents или options.php. Не делайте: модуль ради одной строки в init.php.
Создайте каркас папок в /local/modules/vendor.module
ID - mycompany.custommodule, папка с тем же именем, класс - mycompany_custommodule.
- Создайте каталог /local/modules/mycompany.custommodule/.
- Добавьте install/index.php с классом mycompany_custommodule extends CModule.
- Положите install/version.php с VERSION и VERSION_DATE.
- Создайте lang/ru/install/index.php для текстов мастера установки.
- Добавьте include.php в корень модуля - сюда пойдёт автозагрузка.
- Создайте lib/ для классов D7, например lib/Service/Logger.php.
- Проверьте, что в списке "Настройки продукта → Модули" появилась строка mycompany.custommodule.
Делайте: MODULE_ID = имя папки. Не делайте: точку в имени класса PHP - синтаксическая ошибка, модуль не появится в админке.
Настройте install/index.php: DoInstall, DoUninstall и ModuleManager
install/index.php регистрирует пакет в b_module, ставит события и копирует файлы.
class mycompany_custommodule extends CModule
{
public $MODULE_ID = 'mycompany.custommodule';
public function DoInstall()
{
ModuleManager::registerModule($this->MODULE_ID);
Loader::includeModule($this->MODULE_ID);
$this->InstallEvents();
$this->InstallFiles();
}
public function DoUninstall()
{
$this->UnInstallEvents();
$this->UnInstallFiles();
ModuleManager::unRegisterModule($this->MODULE_ID);
}
}
Типичная ошибка: класс из lib/ вызывают до registerModule. Порядок: b_module → includeModule → сервисы. Делайте: version.php в конструкторе. Не делайте: lib/ до includeModule в DoInstall.
Подключите include.php и автозагрузку классов из lib/
includeModule подключает include.php, где регистрируют автозагрузку классов lib/ без ручного require_once.
<?php
use Bitrix\Main\Loader;
Loader::registerAutoLoadClasses('mycompany.custommodule', [
'Mycompany\\Custommodule\\Service\\Logger' => 'lib/Service/Logger.php',
]);
Namespace: mycompany.custommodule → Mycompany\Custommodule. Проверка: includeModule true и new Logger() без fatal. Настройки - options.php, см. Option API. Делайте: registerAutoLoadClasses в include.php. Не делайте: пустой include.php при lib/.
Установите модуль через админку и проверьте подключение
"Настройки продукта → Модули" → Установить. Проверьте: includeModule true, класс lib/ создаётся, после удаления нет хвостов. Компонент - IncludeComponent, как в гайде по компоненту. Делайте: тест на копии. Не делайте: правку b_module вручную.
Разберите типовые ошибки: модуль не виден, includeModule false, Class not found
| Симптом | Что проверить | Ожидаемый результат |
|---|---|---|
| Модуль не в списке админки | Путь /local/modules/{ID}/, синтаксис install/index.php, класс vendor_module | Строка появляется без правки ядра |
| Class not found в DoInstall | Порядок: registerModule → includeModule → классы lib/ | Установка без fatal |
| includeModule === false | Синтаксис include.php, модуль установлен, верный MODULE_ID | true и доступ к классам |
| После удаления висят обработчики | UnInstallEvents до unRegisterModule, DeleteDirFilesEx для компонентов | Чистая b_module_to_module |
Сверьтесь с официальным гайдом. Делайте: симметрию Install/UnInstall. Не делайте: копию в /bitrix/modules.
Получите переносимый модуль: итоговый чек-лист перед коммитом
- Убедитесь, что MODULE_ID совпадает с папкой и классом vendor_module.
- Проверьте install/uninstall на копии - без fatal и хвостов в БД.
- Зафиксируйте include.php с registerAutoLoadClasses для lib/.
- Свяжите с sprint.migration для переноса между dev и prod.
- Закоммитьте только /local/modules/, не трогая /bitrix.
Нужен разбор архитектуры под ваш проект - напишите через контакты. Примеры модулей для интернет-магазинов и порталов - в портфолио.
Автор: Максим Мольков, разработчик 1С-Битрикс.
Источники: архитектура модулей BitrixFramework, создание модуля, API Loader::includeModule.
Частые вопросы
How to bitrix include module?
Call Bitrix\Main\Loader::includeModule('vendor.module') after the prolog. The method loads include.php and returns true if the module is installed and the file has no syntax errors. For a hard dependency use Loader::requireModule() - it throws LoaderException instead of returning false.
What is Loader::includeModule in Bitrix?
Loader::includeModule is the D7 API to connect a module by its MODULE_ID string. It is the modern equivalent of CModule::IncludeModule. The kernel executes include.php from /local/modules/{ID}/ and registers autoloaded classes from lib/ via registerAutoLoadClasses.
Чем свой модуль отличается от кода в init.php?
init.php - для быстрых правок на одном проекте. Модуль даёт установку через админку, version.php и симметричное удаление событий. Один AddEventHandler без опций - начните с init.php.
Где физически лежит модуль?
В /local/modules/vendor.module/. Ядро /bitrix/modules не трогаем. После установки - запись в b_module и обработчики в b_module_to_module.
Почему Loader::includeModule возвращает false?
Три частые причины: модуль не установлен через админку (только папка на диске), синтаксическая ошибка в include.php, неверный MODULE_ID в вызове. Проверьте b_module и откройте include.php в логе PHP.
Нужен ли include.php, если классы только в lib/?
Да. includeModule подключает include.php. Без registerAutoLoadClasses классы из lib/ не найдутся - получите Class not found даже при true от includeModule.
Как удалить модуль без хвостов в базе?
Сначала UnInstallEvents, UnInstallFiles, UnInstallDB, затем unRegisterModule. Проверьте b_module_to_module после удаления.