Событийная модель Битрикс позволяет добавлять логику в стандартные процессы без правки ядра: заказ, авторизация, инфоблок — всё через обработчики. Ниже — короткий обзор старого AddEventHandler, D7 EventManager и собственных событий. Развёрнутый practical-разбор приоритетов, отладки слушателей и защиты от двойного запуска — в отдельном гайде Bitrix D7 EventManager: подписка, приоритеты и отладка.
Старый способ: AddEventHandler
// В /local/php_interface/init.php
AddEventHandler('iblock', 'OnBeforeIBlockElementAdd', function(&$arFields) {
// Принудительно ставим активность
$arFields['ACTIVE'] = 'Y';
});
// Обработчик с классом
AddEventHandler('sale', 'OnSaleOrderSaved', ['\\MyModule\\Handlers\\OrderHandler', 'onOrderSaved']);
Compatible-события (большинство «классических» OnBefore/OnAfter) принимают аргументы по ссылке. Не подставляйте сюда сигнатуру Event $event, если документация модуля её не обещает.
Новый способ: EventManager D7
use Bitrix\Main\EventManager;
$eventManager = EventManager::getInstance();
// Для старых compatible-событий безопаснее так:
$eventManager->addEventHandlerCompatible(
'iblock',
'OnBeforeIBlockElementAdd',
static function (&$arFields) {
$arFields['ACTIVE'] = 'Y';
}
);
// Для событий на Bitrix\Main\Event — addEventHandler + EventResult
$eventManager->addEventHandler(
'sale',
'OnSaleOrderBeforeSaved',
['\\MyModule\\Handlers\\OrderHandler', 'beforeSaved']
);
Путаница «почему обработчик молчит» чаще всего из-за неверного типа подписки или отсутствия автозагрузки класса. Чеклист и findEventHandlers — в гайде по EventManager.
Популярные события для переопределения
| Модуль | Событие | Когда |
|---|---|---|
| main | OnProlog | Начало каждого запроса |
| main | OnBeforeUserLogin | Перед авторизацией |
| main | OnAfterUserLogin | После успешной авторизации |
| iblock | OnBeforeIBlockElementAdd | Перед добавлением элемента |
| iblock | OnAfterIBlockElementAdd | После добавления элемента |
| iblock | OnBeforeIBlockElementDelete | Перед удалением элемента |
| sale | OnSaleOrderSaved | Заказ сохранён |
| sale | OnSaleStatusOrderChange | Изменение статуса заказа |
Создание собственного события
use Bitrix\Main\Event;
use Bitrix\Main\EventManager;
// Объявляем событие
$event = new Event('mymodule', 'OnBeforeProductExport', [
'productId' => $id,
'data' => &$exportData,
]);
$event->send();
// Проверяем результаты обработчиков
foreach ($event->getResults() as $result) {
if ($result->getType() === \Bitrix\Main\EventResult::ERROR) {
throw new \RuntimeException($result->getParameters()['message']);
}
}
Подписка на собственное событие из другого модуля:
EventManager::getInstance()->addEventHandler(
'mymodule',
'OnBeforeProductExport',
function(\Bitrix\Main\Event $event) {
$data = $event->getParameter('data');
$data['extra_field'] = 'значение';
return new \Bitrix\Main\EventResult(
\Bitrix\Main\EventResult::SUCCESS,
['data' => $data]
);
}
);
Регистрация обработчиков в модуле
// InstallEvents / UnInstallEvents — через registerEventHandler
use Bitrix\Main\EventManager;
public function InstallEvents()
{
EventManager::getInstance()->registerEventHandler(
'iblock',
'OnAfterIBlockElementAdd',
$this->MODULE_ID,
'\\MyModule\\IblockHandler',
'afterElementAdd'
);
}
namespace MyModule;
class IblockHandler
{
public static function afterElementAdd(array &$arFields): void
{
if ((int)($arFields['IBLOCK_ID'] ?? 0) !== 10) {
return;
}
// обработка
}
}
registerEventHandler пишет в БД и переживает редеплой; addEventHandler в init.php живёт, пока подключён файл.
Итог
Для новых проектов берите EventManager D7 и явно различайте compatible-события и Bitrix\Main\Event. Простые глобальные хуки можно оставить в init.php. Ядро не трогайте — только события. Если нужна отладка «кто слушает» и защита от дублей — см. практический гайд по EventManager.
