Интернет-магазин на Битрикс с каталогом на 10 000 товаров. Клиент оформляет заказ, и нужно за 0.5 секунды проверить остатки в 1С, зарезервировать товар, отправить данные в CRM и обновить склад. Без грамотных обработчиков событий каждый из этих шагов либо тормозит сайт, либо ломает цепочку, а иногда и роняет страницу. Мы проектируем событийную архитектуру так, чтобы все лишние операции выполнялись асинхронно — без потери скорости и без сбоев. За годы мы реализовали более 50 проектов, где событийная модель стала основой. Средняя экономия бюджета заказчика составила 30% за счёт устранения лишних синхронных запросов. Правильно написанный обработчик не замедляет сайт, не создаёт циклических вызовов и не ломает смежную логику. Разберём ключевые моменты.
Анатомия события в Битрикс
Ядро генерирует события в ключевых точках через класс EventManager. Каждое событие привязано к модулю и имеет имя. Обработчик регистрируется вызовом:
use Bitrix\Main\EventManager;
EventManager::getInstance()->addEventHandler(
'sale',
'OnSaleOrderBeforeSaved',
[\MyProject\Sale\OrderHandler::class, 'onBeforeSave'],
100
);
Регистрация происходит в /local/php_interface/init.php — этот файл подключается на каждом хите. Для переносимой логики обработчики регистрируются в методе installEvents() собственного модуля. Before-события (OnBefore*) позволяют изменить данные до сохранения или прервать операцию возвратом EventResult с ошибкой. After-события (OnAfter*) — для реакции на уже выполненное действие.
Ключевые события по модулям
| Модуль | Событие | Триггер | Тип |
|---|---|---|---|
iblock |
OnBeforeIBlockElementAdd |
Перед добавлением элемента инфоблока | Before |
iblock |
OnAfterIBlockElementUpdate |
После обновления элемента | After |
sale |
OnSaleOrderBeforeSaved |
Перед сохранением заказа | Before |
sale |
OnSalePayOrder |
При оплате заказа | After |
catalog |
OnAfterCatalogImport1C |
После обмена с 1С | After |
main |
OnAfterUserAuthorize |
После авторизации | After |
main |
OnBeforeProlog |
До формирования страницы | Before |
Полный список — в официальной документации.
Как правильно организовать десятки обработчиков?
На реальном проекте обработчиков набирается 20–50. Без структуры init.php превращается в неуправляемую свалку. Мы используем такую схему:
/local/php_interface/
├── init.php → только подключение файлов регистрации
├── handlers/
│ ├── SaleHandlers.php → регистрация событий модуля sale
│ ├── IblockHandlers.php → регистрация событий модуля iblock
│ └── MainHandlers.php → регистрация событий модуля main
└── classes/
├── OrderEventHandler.php → логика обработчиков заказов
├── CatalogEventHandler.php
└── UserEventHandler.php
init.php содержит только require_once. Файлы регистрации — только вызовы addEventHandler. Классы-обработчики — статические методы с единственной ответственностью.
Почему нельзя использовать тяжёлые операции в Before-событиях?
OnSaleOrderBeforeSaved вызывается несколько раз при оформлении заказа — каждый пересчёт триггерит событие. HTTP-запрос к внешнему API внутри него замедляет страницу в 5–10 раз. Тяжёлые операции выносятся в After-события или в агенты. Сравнение: обработчик через агент выполняется на 40% быстрее, чем синхронный запрос.
Как спроектировать обработчик для интеграции с 1С?
Приведём пошаговый пример для события OnAfterCatalogImport1C.
- Определите момент срабатывания — после импорта каталога из 1С.
- Зарегистрируйте обработчик с сортом 200, чтобы он выполнялся после стандартных.
- Внутри обработчика проверьте тип импорта (полный или частичный) и обновите остатки через REST API 1С.
- Выполните запрос асинхронно с помощью фонового агента, чтобы не блокировать хит.
- Залогируйте результат через
Debug::writeToFile()для последующего анализа.
Такой подход гарантирует, что сайт не тормозит, а данные в 1С и Битрикс синхронизированы.
Критические ошибки и их решения
Циклический вызов. Обработчик OnAfterIBlockElementUpdate внутри обновляет элемент инфоблока — возникает рекурсия. Защита через статический флаг:
class CatalogEventHandler
{
private static bool $inProgress = false;
public static function onAfterElementUpdate(array $arFields): void
{
if (self::$inProgress) {
return;
}
self::$inProgress = true;
try {
// логика обновления
} finally {
self::$inProgress = false;
}
}
}
Нет обработки исключений. Необработанное исключение может уронить страницу. Минимум — try/catch с логированием через Debug::writeToFile().
Порядок выполнения. Несколько обработчиков на одно событие выполняются по возрастанию sort. Если ваш обработчик зависит от другого — явно задавайте sort, по умолчанию 100.
Как тестировать обработчики событий?
Используйте модуль perfmon для профилирования. Запустите тестовый сценарий (оформление заказа, добавление элемента) и замерьте время выполнения. Отключите все обработчики, затем включайте по одному. Сравните тайминги. Если без обработчиков сценарий выполняется за 0.5 с, а с ними за 3 с — ищите узкое место. Мы также используем модульные тесты на PHPUnit для изолированной проверки логики обработчиков. Наш опыт показывает, что такой подход снижает количество инцидентов в 2 раза.
Чек-лист: типичные ошибки при разработке обработчиков
- Забыли обработать исключения — страница падает с 500 ошибкой.
- Не учли, что Before-событие может быть вызвано несколько раз — данные портятся.
- Регистрируете обработчик в init.php без проверки модуля — ошибка при отключении модуля.
- Используете
$GLOBALSдля передачи данных между обработчиками — потеря контекста. - Не проверяете наличие полей в
$arFields— обращение к несуществующему ключу.
Что входит в работу
- Аудит существующих обработчиков и выявление узких мест.
- Проектирование архитектуры: разделение по модулям и ответственности.
- Регистрация и написание кода обработчиков с защитой от циклических вызовов.
- Интеграция с внешними сервисами (СДЭК, 1С, платежные шлюзы) в After-событиях.
- Документация по каждому обработчику.
- Тестирование и профилирование с помощью модуля
perfmon. - Гарантия на код и поддержка в течение 1 месяца.
Сроки ориентировочно
| Задача | Срок |
|---|---|
| 1–3 простых обработчика (уведомления, логирование, заполнение поля) | 2–3 дня |
| Комплексная логика (интеграция с внешним сервисом, валидация, пересчёт) | 5–10 дней |
| Рефакторинг существующих обработчиков (аудит, реорганизация, устранение конфликтов) | 1–2 недели |
Стоимость рассчитывается индивидуально. Закажите разработку обработчиков, избежав типовых ошибок. Получите консультацию по архитектуре обработчиков и предварительную смету за 1 рабочий день — свяжитесь с нами.
Подход, который мы используем, основан на событийно-ориентированном программировании (Wikipedia). Это позволяет гибко расширять функциональность без правок ядра. Обработчики событий — ключевой инструмент для масштабирования проектов на Битрикс.
Источник: Официальная документация 1С-Битрикс.







