АйТи Фреш
Главная / Статьи / 1С и базы данных
1С и базы данных

Как я перевожу Битрикс на PHP 8.2/8.4 и UTF-8, когда шаблон застрял в прошлом

Автор: Семёнов Евгений Сергеевич, директор ООО «АйТи-Фреш» · · ~8 мин чтения
Как я перевожу Битрикс на PHP 8.2/8.4 и UTF-8, когда шаблон застрял в прошлом

После переключения PHP главная открылась, админка работает, проверка системы зелёная. А ночью перестал приходить обмен из 1С, утром пропали настройки доставки. Именно такие поломки нужно искать при миграции. Я — Семёнов Евгений Сергеевич, директор ООО «АйТи-Фреш». Покажу, как разделяю обновление ядра, адаптацию коммерческого решения и преобразование данных, где ставлю контрольные точки и при каких результатах останавливаю переход.

1. Сначала определяю конечную конфигурацию

На сентябрь 2026 года оставлять PHP 8.1 постоянной основой проекта я не планирую. Битрикс с 1 февраля 2026 года требует PHP не ниже 8.2.0 и рекомендует ветку 8.4 или выше. Поддержка однобайтовых установок прекращена с main 24.0.0. Поэтому обновить современное ядро, сохранив cp1251, — уже не штатный маршрут. Эти ограничения нужно выяснить до первой установки обновлений. [Требования Битрикса](https://dev.1c-bitrix.ru/learning/course/?COURSE_ID=32&LESSON_ID=2593).

Для нового рабочего состояния я выбираю PHP 8.4, если весь проект проходит проверку. Поддержка безопасности PHP 8.2 заканчивается 31 декабря 2026 года, PHP 8.4 — 31 декабря 2028 года. У PHP 8.1 поддержка сообщества завершилась 31 декабря 2025 года; сопровождение пакетов отдельным поставщиком нужно проверять отдельно. Ветка 8.2 годится как промежуточная остановка с назначенным сроком следующего перехода. [Сроки поддержки](https://www.php.net/supported-versions.php), [завершённые ветки](https://www.php.net/eol.php).

Мой порядок проверки такой: фактические версии ядра → ограничения шаблона и модулей → расширения и настройки PHP → структура и содержимое данных. Порядок изменений немного другой: сначала совместимые подготовительные обновления, затем UTF-8, потом дальнейшее обновление платформы и PHP. В этом различии вся суть. Обнаружить несовместимый модуль нужно заранее, даже если менять его будем на более позднем этапе.

В одном PHP-запросе ядро и подключённый шаблон исполняются одним интерпретатором. Назначить ядру PHP 8.4, а его шаблону PHP 8.1 настройкой пула нельзя.

2. Выясняю, что именно коммерческий шаблон «требует»

Я выписываю версии main, sale, catalog, iblock, search, perfmon и всех сторонних модулей. Рядом — доступность обновлений, требования поставщика и местные изменения. Проверяю /local, старые шаблоны в /bitrix/templates, скопированные компоненты и обработчики событий. Обновление модуля поставщика не доказывает, что обновился когда-то скопированный result_modifier.php. Именно такие файлы легко переживают несколько поколений платформы.

Фраза «PHP 8.1 и cp1251» требует расшифровки. Это минимальная версия PHP, единственная протестированная версия или жёсткое ограничение исполняемого кода? А cp1251 относится к работающему сайту или установочному архиву? У Битрикса предусмотрена перекодировка определённых файлов мастера при установке UTF-8-дистрибутива. Поэтому кодировка исходного пакета сама по себе ещё ничего не доказывает. Сверяю инструкцию, журнал изменений и ответ разработчика решения. [Документация дистрибутивов](https://dev.1c-bitrix.ru/api_help/main/general/wizards/site/9.custom_distr.php).

Дальше выбираю конкретное действие: поддерживаемое обновление поставщика, сопровождаемый патч открытого кода или замену зависимого компонента. С защищёнными файлами свободы меньше. Например, наличие ionCube Loader для PHP 8.4 не гарантирует запуск пакета, закодированного только для PHP 8.1: нужна совместимость самого формата поставки. Здесь требуется подходящая сборка от вендора. Снимать проверку версии в установщике бессмысленно, если исполняемый файл всё равно несовместим. [Разъяснение ionCube](https://blog.ioncube.com/2026/06/08/ioncube-loader-running-existing-encoded-files-on-future-php-versions/).

Если открытый код действительно привязан к однобайтовым строкам, я оцениваю объём переделки до назначения даты переезда. Исправить несколько обработчиков обычно разумно. Брать на собственное сопровождение большой заброшенный модуль — спорное решение, и его стоимость нужно обсуждать прямо. Все изменения поставки сохраняю отдельным патчем: следующее обновление не должно молча вернуть старое поведение.

Пока для обязательного модуля нет рабочего решения, дата переключения production остаётся предварительной.
Как я перевожу Битрикс на PHP 8.2/8.4 и UTF-8, когда шаблон застрял в прошлом — схема

3. Собираю промежуточный маршрут на изолированной копии

Копия должна воспроизводить файлы, базу, настройки PHP и фоновые задания. Дамп без /upload и конфигурации окружения для репетиции недостаточен. Я заранее проверяю восстановление, отделяю кеши и сессии стенда, блокирую настоящие письма, платежи и исходящий обмен. Доступ к стенду ограничиваю. Клон магазина, который отправляет реальные заказы в учётную систему, способен испортить эксперимент ещё до обновления.

Для cp1251 сначала нужны доступные совместимые обновления, позволяющие выполнить конвертацию. Штатный мастер perfmon.utf8 появился в модуле perfmon 23.200.0; это версия модуля производительности, а не main. Беру наиболее свежий совместимый вариант мастера: после первого выпуска исправлялись отдельные случаи преобразования данных. Если необходимые промежуточные пакеты недоступны, выясняю поддерживаемый маршрут у Битрикса, а не собираю ядро из случайных архивов. [История perfmon](https://dev.1c-bitrix.ru/docs/versions.php?lang=ru&module=perfmon).

На исходном PHP 8.1 выполняю преобразование в UTF-8 и проверяю результат, пока это позволяет подготовленная установка. Затем ставлю доступные обновления штатных и сторонних модулей, проверяю работу на PHP 8.2 и устанавливаю обновления, открывшиеся после переключения. До main 24.0.0 кодировка уже должна быть исправлена. Конкретные промежуточные версии определяются зависимостями проекта; универсального номера main, гарантирующего совместимость всех решений, нет. [История главного модуля](https://dev.1c-bitrix.ru/docs/versions.php?lang=ru&module=main).

После стабилизации UTF-8 и обновлённых модулей испытываю PHP 8.4. Между этапами сохраняю согласованные контрольные точки: файлы, базу и конфигурацию. При новой ошибке сразу понятно, какая группа изменений её принесла. Прохождение через 8.2 — мой диагностический приём, обязательной установки каждой промежуточной ветки PHP нет. Если прямой переход подготовлен и проверен, лишняя остановка не нужна.

Частично обновлённое ядро не оставляю рабочим состоянием. Либо завершаю согласованный этап, либо восстанавливаю его контрольную точку.

4. Проверяю байты, сериализацию и итоговый utf8mb4

Перед конвертацией сравниваю заявленные кодировки столбцов с фактическими данными. Для подозрительных записей смотрю HEX() и известные русские строки. Название cp1251 в схеме не исключает, что старый импорт записал туда UTF-8-байты. Если преобразовать их повторно, получатся кракозябры. Особенно внимательно разбираю собственные TEXT/BLOB-поля, историю обмена и настройки сторонних модулей. Для смешанного содержимого нужен отдельный разбор, автоматически угадать происхождение каждой записи нельзя. [Правила преобразования MySQL](https://dev.mysql.com/doc/refman/8.4/en/charset-conversion.html).

Самая неприятная ловушка — сериализованные значения. Слово «Кран» занимает четыре байта в cp1251 и восемь в UTF-8. Если перекодировать готовую сериализованную строку, оставив длину s:4:, структура повредится. Для известного формата я разбираю исходное значение, преобразую текстовые ключи и значения, затем сохраняю заново. Сжатые данные требуют дополнительной распаковки. Штатный мастер предпочитаю массовому ALTER TABLE, но покрытие нестандартных полей проверяю отдельно. Универсальной регуляркой длины не чиню. [Предупреждение Битрикса о сериализации](https://dev.1c-bitrix.ru/learning/course/?COURSE_ID=43&LESSON_ID=7495).

После мастера отдельно проверяю utf8mb4. В требованиях 2026 года для MySQL 8/9 указана сортировка utf8mb4_0900_ai_ci, для MariaDB 10/11 — utf8mb4_unicode_ci. Старый мастер может оставить промежуточный utf8mb3. Кириллица при этом будет читаться, но полного Unicode ещё нет. Дальнейшее преобразование репетирую отдельно: проверяю столбцы, индексы, сравнение строк и возможные конфликты уникальности. Одной смены значения по умолчанию у базы недостаточно. [Требования Битрикса](https://dev.1c-bitrix.ru/learning/course/?COURSE_ID=32&LESSON_ID=2593), [переход на четырёхбайтовый UTF-8](https://dev.mysql.com/doc/refman/8.4/en/charset-unicode-conversion.html).

Затем согласую настройки исторической установки: BX_UTF, секцию 'utf_mode' в .settings.php, региональные настройки, default_charset и фактическую инициализацию соединения с БД. Флаги сами данные не преобразуют. Проверяю языковые файлы, включаемые области, имена файлов и URL; текст сохраняю без BOM. Устаревшую mbstring.func_overload не возвращаю: механизм удалён ещё в PHP 8.0. После преобразования обновляю кеши и сессии. [Настройки миграции](https://dev.1c-bitrix.ru/learning/course/?COURSE_ID=43&LESSON_ID=7495), [удаление перегрузки mbstring](https://www.php.net/manual/en/mbstring.overload.php).

Внешний CSV может остаться в Windows-1251 по договорённости с получателем. Преобразование делаю на границе обмена; внутренние данные сайта храню в UTF-8.

5. Испытываю PHP вместе с расширениями и собственным кодом

Команда php -v в SSH показывает версию CLI. Сайт может обслуживаться другим FPM, с другим php.ini и другим набором расширений. Поэтому сверяю PHP_VERSION, PHP_SAPI, загруженные ini и расширения через закрытый диагностический запрос, затем проверяю CLI отдельно. В cron указываю нужный бинарник явно. Иначе после успешного переключения сайта ночной импорт продолжит исполняться старым PHP. [Как PHP загружает конфигурацию](https://www.php.net/manual/en/configuration.file.php).

Проверяю mysqli, mbstring, XML, GD и остальные зависимости установки; отдельно — curl, zip, intl, SOAP, Redis или загрузчик защищённого кода, если они нужны модулям. Установленное расширение ещё должно иметь нужные возможности: например, поддержку используемых форматов изображений. Прогоняю именно операции приложения. Список из php -m полезен для сравнения окружений, но работоспособность генератора документов он не доказывает.

В собственном коде на PHP 8.2 ищу создание необъявленных свойств, на PHP 8.4 — в том числе неявно nullable-параметры вида function load(string $id = null). Для такого параметра явно указываю ?string, проверив контракт вызовов. Это примеры deprecated, а не автоматические фатальные ошибки. Но вывод предупреждения способен испортить AJAX-ответ, а обработчик ошибок — превратить его в исключение. Проверяю также изменения промежуточной ветки 8.3. [Изменения PHP 8.2](https://www.php.net/manual/en/migration82.deprecated.php), [изменения PHP 8.4](https://www.php.net/manual/en/migration84.deprecated.php).

На стенде включаю error_reporting = E_ALL и log_errors = On, оставляя display_errors = Off. Сначала устраняю исключения, нарушения данных и сломанные сценарии. Deprecated фиксирую отдельными задачами. Для Composer-пакетов проверяю реальные платформенные требования: check-platform-reqs игнорирует подмену версии через config.platform. Проверка синтаксиса полезна, но выполнения обработчика заказа не заменяет. [Команда Composer](https://getcomposer.org/doc/03-cli.md#check-platform-reqs).

Имена бинарников зависят от окружения. Проверки выполняю тем PHP, который действительно будет обслуживать сайт и задания.

6. Разбор условного стенда: каталог ООО «Вектор»

Разберу модельный проект ООО «Вектор»: название, объёмы и результаты ниже заданы для учебного сценария, это не отчёт о реальном клиенте. Исходные условия: 42 000 товарных предложений, база 6,4 ГБ, /upload — 38 ГБ, PHP 8.1.34, main ветки 23, MariaDB 10.11 и шаблон с открытым кодом. Стенд получает 4 vCPU, 16 ГБ RAM и диск 250 ГБ. Целевые испытания — PHP 8.2.33 и 8.4.25; существование этих выпусков подтверждается журналом PHP. [История выпусков](https://www.php.net/ChangeLog-8.php).

В сценарий закладываю три дефекта: 37 сериализованных настроек собственного калькулятора, жёсткую перекодировку входящего CSV из cp1251 и устаревший обработчик шаблона. На этапе UTF-8 калькулятор проверяется отдельно от каталога. Его настройки преобразуются через разобранную структуру, а импорт получает явный параметр кодировки источника. После этого повторный импорт уже UTF-8-файла не проходит через лишнее преобразование. Проверяю наименования, артикулы, цены и сохранение настроек после повторного входа.

Для целевого пула задаю приведённый ниже фрагмент, сохраняя существующие user, group, listen и права сокета. Это стартовая конфигурация данного стенда. Значение pm.max_children затем уточняю по памяти процессов и очереди запросов; memory_limit ограничивает отдельный скрипт и не равен необходимой памяти сервера. Фоновый обмен запускается явным бинарником PHP 8.4. Во время проверки версия MariaDB остаётся прежней, чтобы не добавлять ещё одну независимую причину ошибок. [Параметры PHP-FPM](https://www.php.net/manual/en/install.fpm.configuration.php).

Заданный итог модельной репетиции: 30 контрольных сценариев проходят на PHP 8.4, все 37 настроек читаются повторно, два последовательных обмена сохраняют 42 000 предложений без дублей. Для планирования принимаем 46 минут на преобразование и проверки, 18 минут на восстановление; это иллюстративные значения, которые на вашем проекте нужно измерить. Главная страница в таком сценарии проходит проверку раньше калькулятора. Поэтому разрешение на выпуск даёт проверка данных и обмена, а не внешний вид.

Числа стенда нельзя переносить в обещание простоя. Объём изменяемых таблиц, индексы, скорость диска и нестандартные форматы определяют фактическое время.

7. Выпускаю после проверки записи и репетиции отката

Перед переключением прохожу критичные операции с холодным и прогретым кешем. Создаю данные, перечитываю их новым запросом, изменяю и выгружаю наружу. Для кириллицы использую контрольные строки с Ё, кавычками и длинным тире; четырёхбайтовый символ проверяю в поле, где приложение его допускает. Отдельно запускаю поиск после переиндексации, письма, обработчики событий и фоновые задания. Непроверенный обязательный сценарий для меня означает незавершённую миграцию.

На выпуске останавливаю запись: оформление заказов, административные изменения, обмен, очереди и задания, которые меняют базу. Создаю финальную согласованную копию и повторяю отрепетированную процедуру на свежих данных. После переключения перезапускаю нужные процессы, проверяю OPcache, очищаю кеш приложения и выполняю короткую приёмку. Обслуживание фоновых задач включаю осознанно, чтобы старый и новый узлы не начали выполнять их одновременно.

Откат определяется тем, что успело измениться. Для одной замены интерпретатора иногда достаточно вернуть прежний PHP. После изменения схемы или кодировки нужны согласованные файлы, база и конфигурация. Если новый сайт уже принял заказы, восстановление старого дампа их потеряет: сначала сохраняю и сверяю новые операции по подготовленному плану. Поэтому окончательное решение принимаю до открытия записи, а затем наблюдаю хотя бы полный цикл обмена и регламентных задач.

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

Частые вопросы

Можно сразу перейти с PHP 8.1 на PHP 8.4?

Да, если подготовлены ядро, шаблон, зависимости и данные, а копия прошла испытания. Промежуточный PHP 8.2 помогает локализовать ошибки, но не является обязательной ступенью языка.

Достаточно включить BX_UTF и изменить charset базы?

Нет. Настройки должны соответствовать преобразованным файлам, значениям в БД и соединению приложения. Сериализацию и собственные форматы проверяют отдельно.

Что делать, если поставщик действительно поддерживает только PHP 8.1?

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

Нужно ли переводить внешний обмен на UTF-8?

Не обязательно. Согласованную Windows-1251 можно сохранить во внешнем формате, выполняя однократное преобразование при чтении или формировании файла.

Подготовим миграцию вашего Битрикса
Предлагаю начать с аудита вашей установки и репетиции миграции на копии — эту техническую работу разберём в «АйТи-Фреш». Если проект затрагивает бухгалтерское сопровождение, для учётной части предлагаю услуги rf-buh.
Бесплатная консультация →
© ООО «АйТи-Фреш» · Москва · Все статьи