Работа с эмодзи
В MySQL кодировка utf8_general_ci поддерживает максимум три байта на символ. Эмодзи занимают четыре байта.
При сохранении четырехбайтного символа в базу данных:
-
запись прерывается на символе эмодзи,
-
весь последующий текст теряется,
-
система возвращает ошибку записи.
Конвертация базы данных в utf8mb4_general_ci изменяет структуру таблиц и индексов. Ее не выполняют на работающих проектах.
Для решения задачи используйте класс \Bitrix\Main\Text\Emoji. Он преобразует эмодзи в безопасный формат перед сохранением и восстанавливает исходные символы при чтении. Это позволяет полноценно работать с эмодзи без изменения кодировки базы данных.
Как работает преобразование
Класс \Bitrix\Main\Text\Emoji заменяет четырехбайтные символы на текстовое представление в формате :код:. Каждый байт кодируется двумя шестнадцатеричными символами, поэтому код содержит ровно восемь символов.
-
при сохранении: 😊 ->
:0001f60a:, -
при чтении:
:0001f60a:-> 😊.
Класс обрабатывает все четырехбайтные символы: эмодзи, иероглифы и специальные символы. Если последовательность вида :код: не соответствует эмодзи, она остается без изменений. Текст без четырехбайтных символов не изменяется.
Настроить обработку эмодзи в ORM
ORM позволяет работать с таблицами базы данных через классы-модели. Для автоматической обработки эмодзи укажите функции обратного вызова в описании полей модели.
Используйте два параметра:
-
save_data_modification— вызывает функцию\Bitrix\Main\Text\Emoji::encodeперед записью данных в базу, -
fetch_data_modification— вызывает функцию\Bitrix\Main\Text\Emoji::decodeпри чтении данных из базы.
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\Text\Emoji;
return [
'TITLE' => [
'data_type' => 'string',
'validation' => [static::class, 'validateTitle'],
'title' => Loc::getMessage('CHAT_ENTITY_TITLE_FIELD'),
'save_data_modification' => [Emoji::class, 'getSaveModificator'],
'fetch_data_modification' => [Emoji::class, 'getFetchModificator'],
],
];
Параметры save_data_modification и fetch_data_modification настраиваются один раз в описании полей. После этого не вызывайте методы \Bitrix\Main\Text\Emoji::encode и \Bitrix\Main\Text\Emoji::decode вручную — преобразование выполняется автоматически.
Сохранить эмодзи без ORM
При прямой работе с базой данных преобразуйте текст перед сохранением.
use Bitrix\Main\Application;
use Bitrix\Main\Text\Emoji;
$request = Application::getInstance()->getContext()->getRequest();
$text = (string)$request->getPost('comment');
$encodedText = Emoji::encode($text);
// Сохраните $encodedText в базу данных
Метод encode заменяет каждый четырехбайтный символ на шестнадцатеричное представление в формате :код:. Результат безопасен для записи в кодировку utf8_general_ci.
Восстановить эмодзи при выборке
После получения текста из базы данных преобразуйте его обратно в читаемый вид.
// При подготовке данных для вывода в шаблон
use Bitrix\Main\Text\Emoji;
/** @var array $result */
$dbText = (string)($result['COMMENT'] ?? '');
$decodedText = Emoji::decode($dbText);
// Используйте $decodedText в шаблоне
Метод decode ищет последовательности вида :код:, проверяет их валидность по паттерну эмодзи и заменяет на исходный символ. Невалидные последовательности остаются без изменений.
Использовать CTextParser
CTextParser — встроенный класс Bitrix Framework для безопасного вывода и обработки текста в шаблонах. Если в проекте настроен CTextParser с обработкой эмодзи, дополнительный вызов decode не требуется. Проверьте конфигурацию парсера в вашем проекте.
// В компоненте при подготовке данных для шаблона
$parser = new \CTextParser();
$textFromDatabase = (string)$textFromDatabase;
$result = $parser->convertText($textFromDatabase);
// $result содержит текст с корректно отображаемыми эмодзи
Проверить работу решения
Выполните проверку в четыре шага.
-
Сохраните текст с эмодзи через настроенный метод: с
encodeили ORM. -
Откройте запись в базе данных и убедитесь, что эмодзи представлены как
:код:. -
Выведите текст на страницу сайта.
-
Проверьте, что эмодзи отображаются корректно и текст после них не обрезан.