Буквально в прошлой статье, я сетовал на отсутствие интересных задач на работе. И уже сегодня посчастливилось столкнуться с одной интересной проблемой, которая заставила «порыться» в интернете и поломать голову в поисках решения.
На одном из сайтов, клиент захотел добавлять текста, внутри которых помимо стандартных символов, могут быть использованы emoji symbols. По-русски они называются «эмотиконы» и выглядят как смайлики различных форматов. Если вы частый гость instagram и имеете привычку время от времени выкладывать свои фотки с крутыми фильтрами в сеть, то наверняка могли видеть подобные символы в подписях к фотографиям, а возможно и сами ими пользовались. Эти самые «смайлики» и стали причиной написания статьи.
Что такое эмотиконы(emoji symbols)?
Для начала небольшой теоретический экскурс. Эмотиконы – это символы, один из блоков юникода, которые появились относительно недавно. И с каждой новой версией юникода, количество таких символов увеличивается, поскольку спрос на них растет. И видимо эта статья когда-нибудь станет популярной(я на это надеюсь), ведь проблема хранения таких символов будет возникать все чаще. Почему проблема? Потому, что для одного emoji требуется 4 байта, когда для других символов из стандартных алфавитов(русский, английский, немецкий и тд), используемых повседневно, достаточно 3 байт. С хранением 3х-байтовых символов всегда хорошо справлялась кодировка utf-8, но тут ее возможности закончились. И ей на смену приходят uft16, utf32 и utf8mb4, способные без проблем хранить многобайтовые символы.
Подробнее про эмотиконы почитать можно тут: ссылка
Emoji в Mysql
Основная проблема найдена – кодировка символов. Осталось ее решить. Хранить текст со спецсимволами будем в Mysql. Начиная с версии 5.5, Mysql умеет работать с кодировками uft16, utf32 и utf8mb4. Но в данном случае достаточно использовать кодировку utf8mb4, она является той же самой utf-8, только более вместительной и соответственно более тяжелой.
Создадим для эксперимента тестовую базу данных с именем test_db. Она будут состоять из одной таблицы test_tbl, которая в свою очередь, будет состоять из двух полей: id INT(11) и text VARCHAR(50). Этого будет достаточно для тестов.
Код создания базы данных и таблицы:
CREATE DATABASE IF NOT EXISTS `test_db`; USE `test_db`; CREATE TABLE IF NOT EXISTS `test_tbl` ( `id` int(11) NOT NULL AUTO_INCREMENT, `text` varchar(50) COLLATE utf8mb4_bin NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; INSERT INTO `test_tbl` (`id`, `text`) VALUES (1, 'test ТУТ_ЭМОТИКОН test текст ТУТ_ЭМОТИКОН');
Эмотиконы можно скопировать тут: ссылка.
Пример вывода эмотиконов с помощью php
Пример запроса к базе данных и вывод строки с эмотиконами и русскими символами:
<?php // задаем кодировку страницы header('Content-type: text/html; charset=utf-8'); // подключение к базе данных $link = mysqli_connect("127.0.0.1", "root", "", "test_db"); // устанавливаем кодировку utf8mb4 для текущего соединения mysqli_set_charset($link, "utf8mb4"); // делаем запрос к БД if ($result = mysqli_query($link, 'SELECT * FROM test_tbl LIMIT 1')) { // получаем результат $row = mysqli_fetch_assoc($result); // выводим текст с эмотиконами и русскими символами echo $row["text"]; }
Послесловие
Самое интересное, что движок, на котором работает блог, не сумел сохранить спецсимволы. Поэтому в коде для создания базы данных присутствует «ТУТ_ЭМОТИКОН» вместо самих эмотиконов. Для тестирования можете скопировать несколько спецсимволов на сайте: тут.