B3x.by
16 июня 2026 г. · Bitrix · PHP8 · маркетплейс-модуль · hotfix · post-mortem

Один undefined constant в покупном модуле ронял весь сайт на PHP 8.2

После обновления платформы сайт начал отдавать фатальную ошибку на каждой странице — но только новым посетителям. Причина пряталась в покупном модуле с маркетплейса, который обращался к константе ядра, которой в новой версии больше нет. Показываем, как закрыли это правкой в одну строку, не тронув ни ядро, ни сам модуль.

Симптом

Сайт услуг на 1С-Битрикс, собранный на покупном шаблоне с маркетплейса. Главная и внутренние страницы падали в hard fatal — но воспроизводилось это только для новых сессий, у которых гео-данные ещё не заполнены. То есть первый заход нового посетителя = белый экран с ошибкой.

Разведка

Трасса вела из header.php (он на каждой странице подтягивает блок регионов) в компонент регионов и дальше в метод определения региона по IP. Текст ошибки:

Undefined constant Bitrix\Main\Service\GeoIp\Manager::INFO_NOT_AVAILABLE.

Причина

Покупной модуль регионов сравнивал результат определения гео с константой Manager::INFO_NOT_AVAILABLE. В установленной версии ядра (main 26.400) такой константы нет — метод возвращает Result|null. На PHP 8.2 обращение к несуществующей константе класса — это уже не «тихий» null, а фатальная ошибка. Баг вендорского модуля, не ядра, и срабатывал он ровно там, где гео ещё не определено, — у новых посетителей.

Что сделали

Правку вынесли в слой local/, оставив файлы модуля нетронутыми (переживёт его будущие обновления):

  • через init.php подгрузили патч-копию класса до того, как сработает ленивая автозагрузка модуля;
  • в копии заменили сравнение с несуществующей константой на честную проверку результата (if ($result) { ... }) — фактически одна строка;
  • аккуратно поправили путь загрузки языковых сообщений, чтобы копия из local/ их находила.

Ядро и сам модуль не трогали. Reflection подтвердил, что теперь грузится наша копия класса — даже если вернуть файл модуля в исходное, «сломанное» состояние.

Результат

php -l чист, свежая сессия отдаёт HTTP 200 без единого маркера ошибки. Изменение — буквально одна строка кода, но она вернула сайту работоспособность для всех новых посетителей. Правильное место для фикса чужого бага — не ядро и не файлы модуля, а local/: так обновления не затрут заплатку.

Имя клиента не раскрываем по NDA. Цифры и подход — реальные.