Не удается сохранить emoji в базе данных

СИТУАЦИЯ :

Извините заранее, если этот вопрос уже задан, но решения для меня не работают.

Независимо от того, что я пытаюсь, я не могу хранить emoji в моей базе данных. Они сохраняются как ???? ,
Единственные emojis, которые были правильно сохранены, – это те, которые требуют только 3 байта, например, застенчивое лицо или солнце.

Фактический utf8mb4 не работает.

Снимок экрана базы данных

Он был протестирован как на Android, так и на Ios. С такими же результатами.

ВЕРСИИ :

Mysql: 5.5.49
CodeIgniter: 3.0.0

ШАГИ :

  1. Я изменил набор символов базы данных и свойства сортировки.

    ALTER DATABASE my_database CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci

  2. Я изменил набор символов и свойства сортировки.

    ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci

  3. Я установил каждое поле таблицы, где это возможно, в качестве кодировки: UTF-8(ut8mb4) и Collation: utf8mb4_unicode_ci

  4. Я изменил соединение с базой данных в приложении CodeIgniter.

  5. Я запустил следующее: SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci

  6. Наконец, я также пробовал это: REPAIR TABLE table_name; OPTIMIZE TABLE table_name; REPAIR TABLE table_name; OPTIMIZE TABLE table_name;

Все должно быть настроено правильно, но все же оно не работает.

НАСТРОЙКИ БАЗЫ ДАННЫХ :

Это результат выполнения следующей команды:

 `SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';` 

Настройки базы данных

НАСТРОЙКИ ТАБЛИЦЫ :

Сводка таблицы структуры таблицы:

Настройки таблицы

ПОДКЛЮЧЕНИЕ БАЗЫ ДАННЫХ :

Это настройки подключения базы данных в файле database.php (обратите внимание, что это не единственная база данных, есть и другие, которые подключаются с помощью utf8)

 $db['my_database'] = array( 'dsn' => '', 'hostname' => PROJECT_DATABASE_HOSTNAME, 'username' => PROJECT_DATABASE_USERNAME, 'password' => PROJECT_DATABASE_PASSWORD, 'database' => PROJECT_DATABASE_NAME, 'dbdriver' => 'mysqli', 'dbprefix' => '', 'pconnect' => FALSE, 'db_debug' => TRUE, 'cache_on' => FALSE, 'cachedir' => '', 'char_set' => 'utf8mb4', 'dbcollat' => 'utf8mb4_unicode_ci', 'swap_pre' => '', 'encrypt' => FALSE, 'compress' => FALSE, 'stricton' => FALSE, 'failover' => array(), 'save_queries' => TRUE ); 

НАСТРОЙКИ MY.CNF :

Это все содержимое файла my.cnf:

 [mysqld] default-storage-engine=MyISAM innodb_file_per_table=1 max_allowed_packet=268435456 open_files_limit=10000 character-set-client-handshake = FALSE character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci [client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 по [mysqld] default-storage-engine=MyISAM innodb_file_per_table=1 max_allowed_packet=268435456 open_files_limit=10000 character-set-client-handshake = FALSE character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci [client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 

ВОПРОС :

Вы знаете, почему это не работает? Я что-то упускаю?

HYPHOTESIS 1 :

Я не уверен, но причиной проблемы может быть следующее:

Как вы можете видеть в my.cnf, character-set-server задан как utf8mb4 :

Но после запуска запроса в базе данных:

SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';

Результатом является то, что character-set-server = latin1

Вы знаете, почему? Почему на самом деле не обновляется?

HYPHOTESIS 2 :

Приложение использует несколько разных баз данных. Этот параметр установлен в utf8mb4, но все остальные установлены в utf8. Это может быть проблемой, даже если они являются разделенными базами данных?

Спасибо!

РЕДАКТИРОВАТЬ:

Это результат SHOW CREATE TABLE app_messages;

 CREATE TABLE `app_messages` ( `message_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `project_id` bigint(20) NOT NULL, `sender_id` bigint(20) NOT NULL, `receiver_id` bigint(20) NOT NULL, `message` text COLLATE utf8mb4_unicode_ci, `timestamp` bigint(20) DEFAULT NULL, `is_read` enum('x','') COLLATE utf8mb4_unicode_ci DEFAULT NULL, PRIMARY KEY (`message_id`) ) ENGINE=InnoDB AUTO_INCREMENT=496 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci 

EDIT 2:

Я выполнил следующую команду:

 INSERT INTO app_messages (message_id, project_id, sender_id, receiver_id, message, timestamp, is_read) VALUES ('496','322','77','188', '😜' ,'1473413606','x'); 

И другие два аналогичные с 😂 и 👻

Они были вставлены в таблицу без проблем:

введите описание изображения здесь

Но в самом приложении я действительно вижу ? (на этот раз только один, а не 4)

Единственный способ, который я знаю, получить? для Emoji не должно быть указано столбец utf8mb4 . Я понимаю, что вы, по-видимому, определили, что столбец объявлен таким образом, но запустите SHOW CREATE TABLE table_name; для дальнейшего подтверждения.

По умолчанию система, база данных по умолчанию и таблица по умолчанию не имеют значения, если столбец перекрывает CHARACTER SET .

Замечание ко всем остальным попыткам ответа: COLLATION имеет значения, для этого вопроса применим только CHARACTER SET .

Сначала загружается my.cnf , затем conf.d/*.cnf .

Вместо изменения my.cnf * (который может быть переопределен конфигурациями в conf.d/*.cnf ), создайте настраиваемую конфигурацию переопределения, например conf.d/90-my.cnf .

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

Чтобы перезагрузить новую конфигурацию, см. « Перезагрузка без перезагрузки службы MySQL» .

Пример структуры конфигурации (Linux)

 . ├── conf.d │  ├── 90-my.cnf │  ├── conn.cnf │  ├── my5.6.cnf │  └── mysqld_safe_syslog.cnf ├── debian.cnf ├── debian-start └── my.cnf 

conf.d / 90-my.cnf

 # https://mathiasbynens.be/notes/mysql-utf8mb4 # http://stackoverflow.com/q/3513773/934739 [client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 [mysqld] character-set-client-handshake = FALSE # The server character set and collation are used as default values if the # database character set and collation are not specified in CREATE DATABASE # statements. They have no other purpose. character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci 

Хорошо, наконец, мне удалось заставить его работать! Спасибо всем, кто пытался мне помочь, особенно @Rick James и @Gerard Roche.

ПРЕДЛОЖЕНИЕ:

Если вам нужно работать с emoji, сначала сделайте простые тесты на localhost. Создайте новую базу данных и создайте новое приложение для тестирования.

Если вы выполните шаги, которые я написал в вопросе, или если вы следуете этому руководству: https://mathiasbynens.be/notes/mysql-utf8mb4#utf8-to-utf8mb4, он должен работать.

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

РЕШЕНИЕ:

В моем случае проблема заключалась в настройке базы данных в CodeIgniter. Это была неправильная настройка char_set и сортировки для глупого игнорирования: я переопределял настройки базы данных в функции, которая сохраняет сообщения, чтобы быть уверенным, что она работает с базой данных для мобильных устройств.

ДО:

 function message_save ( $data = FALSE ) { $project_db_config = array(); $project_db_config['hostname'] = 'MY_HOST'; $project_db_config['username'] = 'MY_USERNAME'; $project_db_config['password'] = 'MY_PASSWORD'; $project_db_config['database'] = 'MY_DATABASE'; $mobile_db = $this->load->database( $project_db_config, TRUE ); // other code to save message } 

ПОСЛЕ:

 function message_save ( $data = FALSE ) { $mobile_db_connection = $this->load->database('admin_mobile_mh', TRUE); // other code to save message } 

ВЫВОД:

Приложение должно правильно установить соединение с базой данных. Если вы правильно настроили базу данных, но вы не вносите правильное соединение с вашим приложением, это не сработает.

Поэтому, если вы сталкиваетесь с подобными проблемами, убедитесь, что api правильно настроил char_set как utf8mb4 и db_collat как utf8mb4_unicode_ci .

Вместо varchar вы можете изменить значение, указанное в таблице, следующим образом: utf8mb4

Убедитесь, что все ваши стандартные символы и текстовые поля ваших таблиц преобразованы в utf8mb4 в дополнение к настройке наборов символов клиента и сервера, например, ALTER TABLE mytable charset=utf8mb4, MODIFY COLUMN textfield1 VARCHAR(255) CHARACTER SET utf8mb4,MODIFY COLUMN textfield2 VARCHAR(255) CHARACTER SET utf8mb4; и так далее.

Привет, я использовал EMOJI в android, и я сохранил его в базе данных orm с помощью EMOJI_INDEX. Я сохранил в db в обычном сообщении в строковой форме, но когда я получаю это время, я проверяю, есть ли какие-либо emoji, затем преобразуйте его туда processemoji.

 textMessage.setText(getItem(pos).file != null ? "":EmojiUtil.getInstance(context).processEmoji(getItem(pos).message, textMessage.getTextSize())); 

Взгляните отсюда, как я изменил Emoji_Index для обработки

 if (emojiImages == null || emojiImages.isRecycled()) { InputStream localInputStream; try { localInputStream = context.getAssets().open("emoji/emoji_2x.png"); Options opts = new Options(); opts.inPurgeable = true; opts.inInputShareable = true; emojiImages = BitmapFactory.decodeStream(localInputStream, null, opts); } catch (IOException e) { return Html.fromHtml(paramString); } } 

Для получения дополнительной информации смотрите здесь . Спасибо, что это поможет вам.

У меня была проблема с версией сервера, на linux. Мне пришлось вручную изменить файл database_interface.lib.php и вокруг этого

if (! PMA_DRIZZLE) {if (! empty ($ GLOBALS ['collation_connection'])) {

измените его так, чтобы оно стало следующим: (обратите внимание на ссылки utf8mb4_unicode_ci )

  // Skip charsets for Drizzle if (!PMA_DRIZZLE) { if (! empty($GLOBALS['collation_connection'])) { PMA_DBI_query("SET CHARACTER SET 'utf8mb4';", $link, PMA_DBI_QUERY_STORE); $set_collation_con_query = "SET collation_connection = '" . PMA_Util::sqlAddSlashes($GLOBALS['collation_connection']) . "';"; PMA_DBI_query( $set_collation_con_query, $link, PMA_DBI_QUERY_STORE ); } else { PMA_DBI_query( "SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci';", $link, PMA_DBI_QUERY_STORE ); } } 

Обновленный ответ

Вы можете попробовать charset utf8 collation utf8_unicode_ci вместо utf8mb4_unicode_ci .

запустить этот запрос

 ALTER TABLE table_name CHANGE `column_name` `column_name` TEXT CHARSET utf8 COLLATE utf8_unicode_ci; 

старый ответ. Вы должны использовать utf8mb4_bin вместо utf8mb4_unicode_ci .

запустить этот запрос

  ALTER TABLE table_name CHANGE `column_name` `column_name` TEXT CHARSET utf8mb4 COLLATE utf8mb4_bin; 

Emojis будет храниться как код и снова преобразован в emojis в приложениях Android и iOS. Я также использовал этот код в своих проектах.