После очередного обновления ядра Битрикс на одном из проектов перестали работать обработчики событий модуля sale. Пользователи не получали уведомления об оплате, заказы не попадали в CRM. Причина — конфликт регистраций в init.php: два модуля вешали обработчики на одно событие с разными sort, и после обновления порядок изменился. Такие ситуации встречаются постоянно. Разработка надёжных PHP-хуков для 1С-Битрикс требует понимания архитектуры ядра и дисциплины кодирования. За 8 лет мы разработали более 50 проектов с событийной моделью и выработали стандарты, исключающие типовые ошибки. Ниже — практические приёмы, которые помогут создать устойчивую событийную архитектуру и сократить время на отладку на 30–40%.
Как работают события в Битрикс
Ядро Битрикс генерирует события в ключевых точках: до операции (Before-события) и после (After-события). Обработчик регистрируется через EventManager:
use Bitrix\Main\EventManager; EventManager::getInstance()->addEventHandler( 'sale', // модуль 'OnSaleOrderBeforeSaved', // событие ['MyHandler', 'onBeforeOrderSave'] // callback ); Регистрация обработчиков — в файле init.php (/local/php_interface/init.php или /bitrix/php_interface/init.php). Для модулей — в методе installEvents(). Документация Битрикс рекомендует указывать параметр sort для контроля порядка.
Before-события позволяют модифицировать данные до сохранения или отменить операцию. Возвращаете EventResult с типом ERROR — операция прерывается. After-события — для реакции на уже совершённое действие: отправить уведомление, записать лог, обновить связанные данные.
Каталог ключевых событий
| Модуль | Событие | Когда срабатывает | Тип |
|---|---|---|---|
iblock |
OnBeforeIBlockElementAdd |
Перед добавлением элемента инфоблока | Before |
iblock |
OnAfterIBlockElementUpdate |
После обновления элемента | After |
sale |
OnSaleOrderBeforeSaved |
Перед сохранением заказа | Before |
sale |
OnSalePayOrder |
При оплате заказа | After |
sale |
OnSaleStatusOrder |
При смене статуса заказа | After |
sale |
OnSaleBasketItemRefreshData |
При пересчёте корзины | Before |
catalog |
OnBeforePriceUpdate |
Перед обновлением цены | Before |
main |
OnAfterUserAuthorize |
После авторизации пользователя | After |
main |
OnBeforeProlog |
До формирования страницы | Before |
Полный список — в файлах модулей: /bitrix/modules/{module}/lib/events.php или в документации.
Дополнительные советы по работе с событиями
- Всегда проверяйте, что обработчик не вызван повторно из-за циклического вызова.
- Для Before-событий не выполняйте тяжёлые операции — они тормозят каждый запрос.
- Используйте
perfmonдля профилирования: он покажет время каждого обработчика (среднее по 100+ вызовам).
Почему стоит выносить обработчики в отдельный модуль?
Модуль надёжнее init.php при обновлениях и миграциях. При деактивации модуля обработчики отключаются автоматически — в случае с init.php нужно чистить код вручную. Если логика универсальна (например, интеграция с платёжным шлюзом) — модуль обязателен. Проектные одноразовые задачи можно оставить в init.php с классами.
Как избежать циклических вызовов?
Обработчик OnAfterIBlockElementUpdate внутри себя обновляет элемент инфоблока → снова срабатывает OnAfterIBlockElementUpdate → бесконечная рекурсия. Решение — статический флаг:
class IblockHandler { private static bool $isProcessing = false; public static function onAfterUpdate($arFields): void { if (self::$isProcessing) return; self::$isProcessing = true; // ... логика self::$isProcessing = false; } } Тяжёлые операции в Before-событиях — ещё одна распространённая ошибка. OnSaleOrderBeforeSaved вызывается 3-5 раз за оформление заказа. Если внутри — HTTP-запрос к внешнему API — оформление тормозит. Решение: тяжёлые операции выносить в After-события или в очередь (агенты, \Bitrix\Main\Event с отложенной обработкой).
Архитектура обработчиков: как организовать код
На реальном проекте обработчиков — десятки. Без организации init.php превращается в свалку. Рекомендуемая структура:
/local/php_interface/ ├── init.php → только require файлов регистрации ├── handlers/ │ ├── sale.php → регистрация обработчиков модуля sale │ ├── iblock.php → регистрация обработчиков модуля iblock │ └── main.php → регистрация обработчиков модуля main ├── classes/ │ ├── SaleHandler.php → классы с логикой обработчиков sale │ ├── IblockHandler.php │ └── MainHandler.php Каждый класс-обработчик — статические методы. Один метод — одно событие. Внутри метода — минимум логики: валидация входных данных, вызов сервисного класса, возврат результата.
Сравнение init.php и модуля
| Критерий | init.php | Отдельный модуль |
|---|---|---|
| Сложность установки | Низкая, просто скопировать файл | Средняя, нужно установить через админку |
| Управление зависимостями | Нет | Есть, через composer |
| Отключение обработчиков | Ручное | Автоматическое при деактивации модуля |
| Повторное использование | Только копипастом | Через composer require |
| Тестируемость | Низкая | Высокая, можно mock-ить модуль |
Отладка обработчиков: инструменты и приёмы
Стандартный способ — Bitrix\Main\Diag\Debug::writeToFile(). Пишет в файл /local/php_interface/debug.log.
Более системный подход — модуль perfmon. Показывает, какие обработчики зарегистрированы на каждое событие и сколько времени каждый потребляет (в миллисекундах). Включается в Настройки → Производительность → Панель производительности.
Для Before-событий модуля sale — особенность: цепочка обработчиков прерывается при первом ERROR. Если ваш обработчик не вызывается — проверьте, не возвращает ли ERROR другой обработчик, зарегистрированный с меньшим sort. Это экономит до 2 часов отладки в месяц.
Процесс разработки обработчиков в нашей команде
- Аудит: анализируем текущие обработчики, выявляем конфликты, узкие места и утечки памяти. Обычно находим 5-10 проблем за 2 часа.
- Проектирование: выбираем архитектуру (модуль или init.php), согласуем с вами.
- Реализация: пишем код с тестированием на стенде, покрываем краевые случаи (например, пустой заказ, некорректные ID).
- Тестирование: нагрузочное тестирование (симулируем 100+ одновременных заказов), проверка совместимости с вашими доработками.
- Деплой: выкатка на бой, мониторинг в течение недели. При проблемах — откат за 15 минут.
Что входит в работу и гарантии
- Аудит текущих обработчиков и выявление конфликтов
- Проектирование архитектуры (модуль или init.php с классами)
- Реализация с тестированием на стенде
- Документация и передача исходников
- Пост-релизная поддержка 1 месяц
Наши инженеры имеют опыт разработки на Битрикс более 8 лет и сертификацию Bitrix. За 50+ проектов мы выработали стандарты, исключающие типовые ошибки. Закажите аудит текущих обработчиков — получите отчёт с рекомендациями по оптимизации. Свяжитесь с нами для консультации. Получите консультацию по архитектуре событий бесплатно.







