Перейти к содержанию

Кодировка определяет, как система хранит и передает текстовые данные: содержимое страниц, языковые файлы, значения из базы данных, письма, файлы обмена и ответы API.

Продукты Bitrix Framework работают в кодировке UTF-8.

Ранее продукты могли работать с однобайтовыми кодировками, например cp1251. В актуальных версиях такие кодировки не поддерживаются: проект должен использовать UTF-8. Старые проекты нужно перевести в UTF-8 перед обновлением.

Как связаны настройки кодировки

В Bitrix Framework за кодировку отвечают несколько уровней настроек. Они не заменяют друг друга, а проверяются и используются системой в разные моменты загрузки ядра.

Кодировка проекта складывается из настроек PHP, конфигурации ядра, региональных настроек и соединения с базой данных. Если один из уровней использует другую кодировку, текст может повредиться при обработке, сохранении или выводе.

|

|| Уровень | Что задает | Где используется || || PHP-окружение | default_charset, mb_internal_encoding() и расширение mbstring. | Должно соответствовать UTF-8, чтобы PHP корректно обрабатывал строки до и после загрузки ядра. || || Конфигурация ядра | Параметр utf_mode в /bitrix/.settings.php. | Мастер конвертации в UTF-8 проверяет, что Configuration::getValue('utf_mode') === true. Параметр не записывает значение в константу SITE_CHARSET. Кодировку текущего контекста ядро получает из региональных настроек. || || Региональные настройки | Объект Culture текущего контекста. Он хранит параметры языка или сайта, включая кодировку. | После инициализации контекста ядро получает кодировку из объекта Culture и определяет константы совместимости SITE_CHARSET и LANG_CHARSET. || || Константы совместимости | BX_UTF, SITE_CHARSET, LANG_CHARSET. | Нужны старому коду и внутренним проверкам. Для нового кода используйте Application::getInstance()->getContext()->getCulture(). || || Соединение с БД | charset в connections.default, команды в after_connect_d7.php, кодировка базы, таблиц и полей. | Должно совпадать с UTF-8-режимом приложения, чтобы данные не повреждались при чтении и записи. || |#

Порядок загрузки:

  1. Ядро подключает /bitrix/php_interface/dbconn.php. В этом файле могут быть ранние настройки PHP и константы совместимости.

  2. Затем ядро подключает modules/main/include/constants.php. Если BX_UTF еще не определена, ядро определяет ее со значением true.

  3. Контекст запроса определяет текущий сайт, язык и объект Culture. Для публичной части объект Culture берется из настроек сайта, для административного раздела — из языка интерфейса.

  4. После инициализации объекта Culture ядро определяет константы совместимости SITE_CHARSET и LANG_CHARSET, которые получают значение $culture->getCharset().

  5. Если опция Главного модуля include_charset равна Y, ядро отправляет HTML-заголовок Content-Type с LANG_CHARSET.

Как получить кодировку текущего контекста

Получить объект Culture текущего контекста можно методом getCulture().

<?php
use Bitrix\Main\Application;

$culture = Application::getInstance()->getContext()->getCulture();
$charset = $culture->getCharset();

Culture хранит параметры языка и сайта текущего запроса. Подробнее в статье Локализация.

Константы SITE_CHARSET, LANG_CHARSET и BX_UTF остаются механизмом совместимости для старого кода. В новом коде используйте объект Culture из текущего контекста. Не используйте константу BX_UTF как источник конкретного значения кодировки: она показывает режим совместимости, а charset текущего контекста хранит Culture.

Для обычной HTML-страницы HTTP-заголовок отправляется автоматически. Ядро читает опцию Главного модуля include_charset со значением по умолчанию — Y.

Content-Type: text/html; charset=UTF-8

Как настроить UTF-8 в проекте

Для корректной работы проекта используйте UTF-8 в окружении, конфигурации, базе данных, файлах и обмене с внешними системами.

Примечание

Параметр utf_mode в .settings.php должен быть включен для проекта в UTF-8:

'utf_mode' => [
    'value' => true,
    'readonly' => true,
],

Этот параметр проверяет мастер конвертации в UTF-8. Он не подменяет региональные настройки сайта и языка: после загрузки ядра кодировка текущего контекста все равно берется из объекта Culture.

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

Совет

PHP

  • В файле php.ini задано default_charset = "UTF-8".

  • Внутренняя кодировка mb_internal_encoding() равна UTF-8.

Конфигурация ядра

  • В /bitrix/.settings.php включена секция 'utf_mode' => ['value' => true, 'readonly' => true].

  • В текущем контексте Application::getInstance()->getContext()->getCulture()->getCharset() возвращает UTF-8.

  • В /bitrix/php_interface/dbconn.php не должно быть настроек для однобайтовых кодировок, например, setlocale(LC_ALL, 'ru_RU.CP1251') или mb_internal_encoding('Windows-1251') для cp1251.

База данных

  • Кодировка соединения с БД соответствует UTF-8.

  • Для MySQL значения character_set_connection, character_set_results должны быть utf8, utf8mb3 или utf8mb4, а правила сравнения строк (collation) — соответствовать выбранной UTF-8-кодировке.

  • Кодировка базы, таблиц и текстовых полей совпадает с кодировкой соединения.

  • В /bitrix/php_interface/after_connect.php и /bitrix/php_interface/after_connect_d7.php нет команд, которые переключают соединение в однобайтовую кодировку.

Файлы проекта

PHP, HTML, JavaScript, CSS, YAML, JSON, языковые файлы и шаблоны сохранены в UTF-8 без BOM.

Почта и экспорт

В заголовках писем, CSV, XML и других файлов указан charset=UTF-8, если формат требует явного указания кодировки.

Как работать с файлами

Сохраняйте исходники проекта в UTF-8 без BOM. Особенно проверяйте файлы, которые выполняются или подключаются как часть проекта:

  • PHP-файлы модулей, компонентов и обработчиков,

  • языковые файлы /lang/<код языка>/,

  • шаблоны сайта и шаблоны компонентов,

  • файлы JavaScript, CSS, YAML и JSON.

Символ BOM в начале PHP-файла может вывести скрытые байты до HTTP-заголовков и нарушить редиректы, авторизацию, скачивание файлов или AJAX-ответы.

Для файлов обмена, CSV и XML проверяйте не только BOM, но и фактическую кодировку входных данных. Если внешний файл приходит не в UTF-8, конвертируйте данные.

<?php
use Bitrix\Main\Text\Encoding;

$source = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/upload/import.csv');
$content = Encoding::convertEncoding($source, 'windows-1251', 'UTF-8');

Метод Encoding::convertEncoding() возвращает данные в целевой кодировке. Принимает строку или массив. Если кодировки совпадают, метод вернет исходные данные без изменений.

Как работать с базой данных

Кодировка приложения и кодировка соединения с базой данных должны совпадать. Если PHP работает в UTF-8, а соединение с БД использует другую кодировку, текст может повредиться при чтении или записи.

Проверяйте настройки БД в двух местах: в параметрах подключения и в файлах, которые выполняются после подключения.

Параметры подключения

В /bitrix/.settings.php секция connections.default описывает подключение к базе данных. Для \Bitrix\Main\DB\MysqliConnection можно указать ключ charset. При подключении ядро передаст значение этого ключа в mysqli::set_charset().

Для UTF-8-соединения MySQL используйте utf8, utf8mb3 или utf8mb4. В новых установках обычно используется utf8mb4.

'connections' => [
    'value' => [
        'default' => [
            'className' => \Bitrix\Main\DB\MysqliConnection::class,
            'host' => 'localhost',
            'database' => 'bx',
            'login' => 'db_user',
            'password' => '***',
            'charset' => 'utf8mb4',
        ],
    ],
],

Подробнее о параметрах подключения читайте в статье Конфигурация БД.

Команды после подключения

После установки соединения по умолчанию D7 ядро подключает файл /bitrix/php_interface/after_connect_d7.php, если в параметрах соединения не указан другой файл include_after_connected.

В этом файле могут быть SQL-команды, которые меняют кодировку соединения. Например, новая установка MySQL добавляет команду SET NAMES для utf8mb4:

<?php
$this->queryExecute("SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'");

Если в проекте есть /bitrix/php_interface/after_connect.php или /bitrix/php_interface/after_connect_d7.php, проверьте, что команды в них не переключают соединение в однобайтовую кодировку.

Встроенная проверка системы сравнивает кодировку соединения, кодировку результатов, правило сравнения строк соединения (collation), кодировку базы, таблиц и текстовых полей. Для MySQL значения character_set_connection и character_set_results должны быть utf8, utf8mb3 или utf8mb4. Значение collation должно соответствовать выбранной UTF-8-кодировке.

Для PostgreSQL проверяйте client_encoding: для UTF-8-соединения значение должно быть UTF8.

Внимание

Не меняйте кодировку базы данных прямым запросом ALTER TABLE без проверки сериализованных данных. В сериализованных строках PHP хранит длину строки в байтах. После некорректной конвертации такие значения перестают читаться.

Как обновить сайт с однобайтовой кодировкой

Проекты с однобайтовой кодировкой нужно перевести в UTF-8, чтобы обновить Главный модуль main до версии 24.0.0 и выше.

Для конвертации используйте мастер Конвертация в utf8. Он доступен с версии Главного модуля 23.200.0 на странице Настройки > Настройки продукта > Список мастеров.

Перед конвертацией выполните подготовительные шаги.

  1. Создайте резервную копию файлов и базы данных. Подробнее в статье Резервное копирование.

  2. Подготовьте тестовую копию сайта.

  3. Выполните конвертацию на тестовой копии сайта.

  4. Проверьте результат: публичную часть, административный раздел, почту, поиск, импорт, экспорт и интеграции.

  5. После успешной проверки выполните изменения на боевом сайте.

Внимание

Не запускайте массовую конвертацию файлов и базы данных на боевом сайте без проверки на тестовой копии. Ошибки в кодировке сложно исправить. Повреждение может затронуть контент, настройки, кеш и сериализованные данные.