Работа с эмодзи

В 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 содержит текст с корректно отображаемыми эмодзи
        

Проверить работу решения

Выполните проверку в четыре шага.

  1. Сохраните текст с эмодзи через настроенный метод: с encode или ORM.

  2. Откройте запись в базе данных и убедитесь, что эмодзи представлены как :код:.

  3. Выведите текст на страницу сайта.

  4. Проверьте, что эмодзи отображаются корректно и текст после них не обрезан.