Регистрация обработчика — это связывание вашей функции с именем события. В 1С-Битрикс есть несколько способов сделать это, и они различаются по времени жизни, месту хранения и формату вызова. Разберём их по порядку и покажем, когда какой применять.
Временная и постоянная регистрация
Все способы делятся на две группы по времени жизни.
| Способ | Хранение | Живёт | Где регистрируют |
|---|---|---|---|
AddEventHandler | В памяти запроса | Один хит | init.php |
RegisterModuleDependencies | Таблица b_module_to_module | Постоянно | DoInstall модуля |
EventManager::addEventHandler | В памяти запроса | Один хит | init.php |
EventManager::registerEventHandler | Таблица b_module_to_module | Постоянно | DoInstall модуля |
Правило простое: то, что подключается на каждом хите (init.php), — временное; то, что должно жить, пока установлен модуль, — постоянное и хранится в БД.
AddEventHandler: классический способ
Самый частый вариант для точечных доработок. Сигнатура: AddEventHandler($fromModuleId, $eventType, $callback, $sort = 100, $fullPath = false, $args = false).
Регистрация метода класса в /local/php_interface/init.php:
AddEventHandler(
'sale',
'OnSaleOrderSaved',
['\App\Handlers\OrderHandler', 'onSaved']
);
Пятый параметр $fullPath позволяет указать путь к файлу, который будет подключён отложенно, только когда событие сработает. Это удобно, чтобы не грузить класс на каждом хите:
AddEventHandler('sale', 'OnSaleOrderSaved',
['OrderHandler', 'onSaved'], 100,
'/local/php_interface/handlers/order.php');
D7: EventManager
Ядро D7 использует объект \Bitrix\Main\EventManager. Для временной регистрации:
use Bitrix\Main\EventManager;
EventManager::getInstance()->addEventHandler(
'main', 'OnAfterUserAdd',
['\App\Handlers\UserHandler', 'onAdd']
);
Для постоянной регистрации из инсталлятора модуля — registerEventHandler с указанием модуля-обработчика:
EventManager::getInstance()->registerEventHandler(
'main', 'OnAfterUserAdd', 'my.module',
'\App\Handlers\UserHandler', 'onAdd'
);
\Bitrix\Main\Event. Параметры достаются через $event->getParameter('ID'), а результат возвращается объектом EventResult.Регистрация из собственного модуля
Постоянные обработчики оформляют в классе установки модуля /local/modules/my.module/install/index.php. В методе DoInstall() вызывают регистрацию, в DoUninstall() — снятие.
public function installEvents() {
RegisterModuleDependencies(
'iblock', 'OnAfterIBlockElementAdd',
'my.module',
'\App\Handlers\Product', 'onAdd'
);
}
Плюс подхода — запись хранится в БД, переживает очистку кэша и не требует правки init.php на каждом сайте. Минус — при отладке о ней легко забыть, потому что в коде init.php её не видно.
Снятие и порядок обработчиков
Постоянную регистрацию снимают зеркальными вызовами:
UnRegisterModuleDependencies($fromModule, $eventType, $toModule, $toClass, $toMethod)— для старого API;EventManager::getInstance()->unRegisterEventHandler(...)— для D7.
Аргументы должны точно совпадать с теми, что были при регистрации, иначе запись не удалится. Временные обработчики снимать не нужно — они живут только текущий хит.
Порядок вызова нескольких обработчиков определяется параметром сортировки (по умолчанию 100): меньшее значение — раньше.
Типичные ошибки
RegisterModuleDependencies дважды с одинаковыми аргументами, в b_module_to_module появятся две записи, и обработчик отработает дважды. Перед регистрацией проверяйте наличие записи.- Класс обработчика должен быть доступен (автозагрузка или подключение файла), иначе будет фатальная ошибка при вызове события.
- Имя модуля-источника и имя события регистрозависимы.
- Для тяжёлых обработчиков используйте отложенное подключение файла (параметр пути), чтобы не грузить код на каждом хите.
Итог
Выбор способа регистрации сводится к вопросу времени жизни: разовая доработка — AddEventHandler в init.php; тиражируемая логика — RegisterModuleDependencies в инсталляторе модуля. D7-методы EventManager — то же самое, но для событий нового ядра.
Мы оформляем обработчики так, чтобы их было легко найти, снять и обновить: постоянные — в модулях с корректными DoInstall/DoUninstall, временные — в структурированном /local/php_interface. Нужна помощь с интеграционной разработкой или поддержкой существующего кода — обращайтесь.
Частые вопросы
В чём разница AddEventHandler и RegisterModuleDependencies?
AddEventHandler регистрирует обработчик только на текущий запрос и вызывается в init.php. RegisterModuleDependencies сохраняет обработчик в таблицу b_module_to_module, и он действует постоянно.
Нужно ли снимать обработчики из init.php?
Нет. Временные регистрации живут только текущий хит и снимаются автоматически. Снимать нужно только постоянные, зарегистрированные через RegisterModuleDependencies или registerEventHandler.
Почему обработчик срабатывает дважды?
Скорее всего, постоянная регистрация была выполнена дважды и в b_module_to_module появились дубли. Проверьте таблицу и удалите лишнюю запись.
Что делает пятый параметр AddEventHandler?
Это путь к файлу с классом обработчика. Файл подключается отложенно, только когда событие срабатывает, что экономит ресурсы на хитах без этого события.
Как зарегистрировать обработчик события D7?
Через EventManager::getInstance()->addEventHandler(module, event, callback) для временной регистрации или registerEventHandler для постоянной, с указанием модуля-обработчика.
Можно ли задать приоритет обработчика?
Да, через параметр сортировки при регистрации. По умолчанию 100, меньшее значение вызывается раньше.
Где хранить класс обработчика?
Удобно в /local/php_interface/ или внутри собственного модуля с автозагрузкой классов. Главное, чтобы класс был доступен в момент вызова события.
Поможем с настройкой и поддержкой Для разработчиков
Поможем с настройкой, доработкой и поддержкой Для разработчиков.