Рефакторинг Битрикс без остановки продаж: ревью кода
Как менять PHP-код, компоненты и запросы в проекте на 1С-Битрикс, не превращая релиз в остановку магазина: безопасная ветка, теневые проверки, обратная совместимость и план отката.

Рефакторинг интернет-магазина на 1С-Битрикс опасен не самим изменением PHP-кода, а моментом переключения: заказ уже создан, оплата ещё не подтверждена, складская система ждёт событие, а новый компонент начал работать по другой логике. Без остановки продаж это решают не одним «аккуратным коммитом», а последовательностью: зафиксировать текущий контракт, отделить чтение от записи, проверить код на копии боевых данных и выпускать изменения небольшими обратимыми шагами.
Сначала зафиксируйте границы рефакторинга
Для проекта на 1С-Битрикс граница проходит не только по файлам PHP. В неё входят настройки инфоблоков, свойства товаров, почтовые события, агенты, обработчики событий, правила URL, интеграции с оплатой и доставкой, а также данные в таблицах модуля. Если менять только класс или шаблон компонента, можно сохранить рабочий код и сломать его окружение.
В качестве базовой точки укажите точную версию 1С-Битрикс и PHP. Для статьи подходит ветка 1С-Битрикс 24.x и новее, но перед работой проверьте номер версии в административной части и совместимость PHP в официальной документации. Поведение модулей и требования к PHP зависят от обновлений, редакции и установленных решений.
Соберите короткий паспорт участка:
- какая страница или бизнес-операция меняется;
- какие компоненты, классы и обработчики событий участвуют;
- какие таблицы и инфоблоки читаются и изменяются;
- какие внешние системы получают уведомления;
- какие фоновые агенты могут повторить или отложить операцию;
- какой признак покажет, что продажи продолжаются: созданный заказ, успешная оплата, переданный статус доставки.
Термин. Контракт компонента — это не только имя метода. Это ожидаемые входные параметры, структура результата, коды ошибок, порядок изменения данных и побочные эффекты, на которые рассчитывают шаблоны и интеграции.
Ревью до изменений: ищите не стиль, а точки риска
Первое ревью должно отвечать на вопрос: где изменение может повлиять на незавершённый заказ. Форматирование и переименование переменных оставьте на потом. В первую очередь проверяйте границы транзакций, повторный запуск обработчиков и запросы внутри циклов.
Что проверять в коде Битрикс
- Загрузку модулей. В файле, который может вызываться отдельно, явно проверяйте подключение нужного модуля через
\Bitrix\Main\Loader::includeModule(). Не полагайтесь на то, что другой компонент уже загрузил его раньше. - Прямой доступ к базе. Сырые SQL-запросы, склеенные из строк, проверяйте отдельно. В них часто прячутся ошибки экранирования, несовместимость с изменившейся схемой и обход бизнес-логики модуля.
- Запросы в цикле. Получение свойств товара или остатков отдельным запросом для каждой позиции быстро превращается в задержку на корзине. Сначала измерьте количество запросов, затем меняйте способ выборки.
- Обработчики событий. Один обработчик может запускаться повторно при импорте, ручном изменении заказа и синхронизации. Проверяйте идемпотентность: повторный запуск не должен создавать второй платёж или дублировать отгрузку.
- Глобальное состояние. Использование
$GLOBALS, сессии и статических переменных усложняет параллельные сценарии. Особенно опасны значения, которые остаются между частями одного долгого процесса. - Кеш. После изменения результата компонента проверьте, когда он очищается. Старый кеш может показывать прежнюю цену, остаток или статус заказа даже после успешного рефакторинга.
Безопасный рефакторинг — это изменение внутреннего устройства при сохранении наблюдаемого поведения. Если поведение не зафиксировано, команда рефакторизует не код, а собственные предположения о нём.
Разделите изменение на совместимые этапы
Не заменяйте старый компонент новым за один релиз. Для магазина безопаснее схема «добавить — переключить — удалить». Она увеличивает число коммитов, зато каждый шаг можно отменить без восстановления всей базы.
- Добавьте новый код рядом со старым. Новый сервис или класс пока не должен менять заказ. На этом шаге вынесите повторяющуюся логику, добавьте логирование входных данных и результата.
- Сделайте совместимый адаптер. Старый компонент продолжает получать прежний массив результата, а внутри вызывает новый код. Это сохраняет шаблоны и снижает число одновременных изменений.
- Переключите один сценарий. Начните с чтения каталога или личного кабинета, но не с оплаты. Если в проекте есть возможность управляемого флага, включайте новый путь для внутреннего пользователя или отдельного тестового сегмента.
- Сравните старый и новый результат. В режиме проверки можно вычислять различия и писать их в журнал, не показывая новый результат покупателю. Не записывайте в лог персональные данные, номера карт и токены.
- Переведите запись на новый путь. Для заказа сначала обеспечьте прежний формат результата для вызывающего кода. Отдельно проверьте повторный запрос после тайм-аута: клиент мог не получить ответ, хотя заказ уже создан.
- Удалите старый путь после окна наблюдения. Срок зависит от трафика и цикла заказов. Для оплаты и доставки это обычно не один час: нужно увидеть хотя бы полный рабочий цикл от оформления до передачи статуса во внешнюю систему.
После каждого шага должна быть проверка. Открывается карточка товара, корзина пересчитывает итог, тестовый заказ получает номер, платёжный статус меняется ожидаемым образом, а в журнале интеграции появляется ровно одно событие.
Как проводить проверку без копирования всей ошибки в прод
Копия проекта должна быть максимально похожа на боевую по версии ядра, PHP, расширениям, настройкам кеша и структуре инфоблоков. Анонимизированная копия базы полезнее пустого стенда: на ней проявляются товары с несколькими единицами измерения, старые заказы и незаполненные свойства.
Для записи используйте отдельные тестовые сущности. Не отправляйте реальные письма, запросы в платёжный шлюз и уведомления клиентам. Внешние интеграции переводите в тестовый режим только если это предусмотрено их официальной документацией. Подмена адреса через случайную настройку опасна: один пропущенный параметр может отправить тестовый заказ в боевую систему.
Минимальный набор проверок для участка заказа:
- товар с одной и несколькими торговыми предложениями;
- нулевой и изменившийся остаток;
- скидка, промокод и округление суммы;
- гость и авторизованный пользователь;
- повторная отправка формы и обновление страницы после оплаты;
- ошибка внешнего сервиса и повторная попытка;
- запуск агента или импорта одновременно с оформлением заказа.
Если автоматических тестов нет, начинайте не с попытки покрыть весь проект, а с тестов на границе риска: расчёт суммы, создание заказа, смена статуса и отправка события во внешнюю систему. Для каждой операции фиксируйте входные данные, ожидаемый результат и допустимое число побочных эффектов.
Сравнивайте подходы по цене отката
| Подход | Что выигрываете | Чем платите | Когда применять |
|---|---|---|---|
| Полная замена компонента | Меньше старого кода после релиза | Сложный откат, много скрытых контрактов | Небольшой изолированный участок с тестами |
| Адаптер поверх нового сервиса | Старый интерфейс сохраняется | Временно живут два слоя | Каталог, корзина и личный кабинет с зависимыми шаблонами |
| Теневая проверка | Можно сравнить результат до переключения | Дополнительные вычисления и риск утечки данных в лог | Расчёт цены, доставки и доступности товара |
| Постепенное включение | Ограниченный радиус ошибки | Нужны флаг, метрики и быстрый откат | Большой магазин с постоянным потоком заказов |
Если новый код меняет одновременно формат данных и способ записи, остановитесь и разделите задачу. Миграцию структуры данных выносите в отдельный контролируемый этап. Иначе при откате приложения старая версия может уже не прочитать новые значения.
Что ломается первым после релиза
Заказ создаётся дважды
Частая причина — повтор формы после тайм-аута или обработчик, который повторно выполняет действие после неясного ответа внешней системы. Для критичных операций храните внешний идентификатор операции и перед повтором проверяйте, не был ли результат уже сохранён. Конкретный механизм зависит от используемого платёжного и интеграционного модуля.
Новый код показывает старые данные
Проверьте кеш компонента, управляемый кеш и кеш на уровне CDN или прокси. Очистка кеша не должна быть первым и единственным решением: сначала определите, какой слой вернул устаревшее значение и какой срок его хранения.
На стенде всё работает, а в проде падает
Сравните версию PHP, расширения, права на файлы, настройки очередей, cron и веб-сервера. В Битрикс одинаковый PHP-код может вести себя по-разному при запуске через веб-запрос и через CLI. Отдельно проверьте окружение агентов и фоновых заданий.
Появились медленные страницы
Не лечите проблему увеличением тайм-аута. Снимите количество SQL-запросов, время ответа базы, время внешних вызовов и долю запросов к кешу. Сравнивайте до и после на одинаковом URL, наборе товаров и уровне параллельности. Если измерений нет, численное улучшение заявлять нельзя.
Как оформить ревью, чтобы его можно было повторить
Ревью должно оставлять след, понятный следующему инженеру. Для каждого замечания указывайте участок, риск и проверку. Формулировка «плохая архитектура» ничего не даёт. Лучше написать: «Обработчик вызывается после изменения заказа и не проверяет внешний идентификатор. При повторной доставке события возможна повторная отправка. Нужен тест на два одинаковых события и журнал результата».
Перед выпуском проверьте:
- есть ли план отката приложения и базы отдельно;
- можно ли выключить новый путь без публикации нового кода;
- кто наблюдает за заказами, оплатами, ошибками PHP и очередями;
- какие значения считаются критическими: число заказов, ошибки оплаты, время ответа, дубли событий;
- когда команда прекращает раскатку и возвращается к старому пути.
Не откатывайте базу автоматически вместе с приложением, если не проверили обратную совместимость. Часто безопаснее оставить новые поля, вернуть старый код и разобрать данные отдельной процедурой. Удаление данных ради «чистого отката» может стоить дороже, чем временный двойной слой.
Что делать дальше
Выберите один денежный сценарий с понятной границей, например расчёт корзины или создание заказа, и составьте карту его вызовов. Зафиксируйте версию 1С-Битрикс, PHP и модулей, затем добавьте проверку на повторную отправку и измерение SQL-запросов. После первого безопасного переключения перенесите тот же процесс на соседний участок, а удаление старого кода планируйте только после полного цикла заказов и проверки журналов интеграций.
Проверка рекламы на риски: Что в макете вызовет вопросы ФАС: превосходные степени, сравнения, обещания результата, маркировка.
Спросить за 40 ₽Источники: Официальная документация API 1С-Битрикс, Официальный портал разработчиков 1С-Битрикс
Частые вопросы
Можно ли рефакторить Битрикс прямо на боевом сайте?
Нужно ли останавливать оформление заказов во время релиза?
Что делать, если после переключения появились дубли заказов?
Как понять, что рефакторинг действительно ускорил сайт?
Что делать, если на другой версии Битрикс код ведёт себя иначе?
Какие подводные камни важны в продакшене?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.