web-dev-qa-db-fra.com

MySQL utf8mb4, Erreurs lors de l'enregistrement d'Emojis

J'essaie de sauvegarder les noms des utilisateurs d'un service dans ma base de données MySQL. Ces noms peuvent contenir des émoticônes comme ???????????????? (juste pour des exemples)

Après avoir cherché un peu, j'ai trouvé ce stackoverflow en se connectant à ce tutorial . J'ai suivi les étapes et il semble que tout est configuré correctement.

J'ai une base de données (jeu de caractères et collation définie sur utf8mb4 (_unicode_ci)), une table appelée TestTable, également configurée de cette manière, ainsi qu'une colonne "Texte" configurée de cette manière (VARCHAR (191) utf8mb4_unicode_ci). 

Lorsque j'essaie de sauvegarder des émoticônes, un message d'erreur s'affiche:

Example of error for shortcake (????):
    Warning: #1300 Invalid utf8 character string: 'F09F8D'
    Warning: #1366 Incorrect string value: '\xF0\x9F\x8D\xB0' for column 'Text' at row 1

Le seul Emoji que j'ai pu sauver correctement était le soleil

Bien que je ne les ai pas tous essayés pour être honnêtes. 

Y a-t-il quelque chose qui me manque dans la configuration?

Remarque: Tous les tests de sauvegarde ne concernaient pas le client. J'utilise phpmyadmin pour modifier manuellement les valeurs et enregistrer les données. Donc, la configuration appropriée du côté client est quelque chose que je prendrai en charge après que le serveur enregistre correctement les émojis. 

Another Sidenote: Actuellement, lors de la sauvegarde des émoticônes, j'obtiens l'erreur comme ci-dessus ou aucune erreur et les données de Username ???? seront stockées sous le nom Username ????. Erreur ou pas d'erreur dépend de la façon dont je sauvegarde. Lors de la création/de l'enregistrement via l'instruction SQL, j'enregistre avec des points d'interrogation, lors de l'édition en ligne, j'enregistre avec des points d'interrogation. Lors de l'édition à l'aide du bouton d'édition, l'erreur est générée.

je vous remercie

EDIT 1: D'accord, je pense donc avoir découvert le problème, mais pas la solution . Il semble que les variables spécifiques à la base de données n'aient pas changé correctement.

Lorsque je suis connecté en tant que root sur mon serveur et que je lis les variables (globales):
Requête utilisée: SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';

+--------------------------+--------------------+
| Variable_name            | Value              |
+--------------------------+--------------------+
| character_set_client     | utf8mb4            |
| character_set_connection | utf8mb4            |
| character_set_database   | utf8mb4            |
| character_set_filesystem | binary             |
| character_set_results    | utf8mb4            |
| character_set_server     | utf8mb4            |
| character_set_system     | utf8               |
| collation_connection     | utf8mb4_unicode_ci |
| collation_database       | utf8mb4_unicode_ci |
| collation_server         | utf8mb4_unicode_ci |
+--------------------------+--------------------+
10 rows in set (0.00 sec)

Pour ma base de données (dans phpmyadmin, la même requête), il ressemble à ceci:

+--------------------------+--------------------+
| Variable_name            | Value              |
+--------------------------+--------------------+
| character_set_client     | utf8               |
| character_set_connection | utf8mb4            |
| character_set_database   | utf8mb4            |
| character_set_filesystem | binary             |
| character_set_results    | utf8               |
| character_set_server     | utf8               |
| character_set_system     | utf8               |
| collation_connection     | utf8mb4_unicode_ci |
| collation_database       | utf8mb4_unicode_ci |
| collation_server         | utf8mb4_unicode_ci |
+--------------------------+--------------------+

Comment puis-je ajuster ces paramètres sur la base de données spécifique? Même si j'ai les premiers paramètres affichés par défaut, lors de la création d'une nouvelle base de données, le second est utilisé comme paramètre.

Edit 2:

Voici mon fichier my.cnf:

[client]
port=3306
socket=/var/run/mysqld/mysqld.sock
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld_safe]
socket=/var/run/mysqld/mysqld.sock

[mysqld]
user=mysql
pid-file=/var/run/mysqld/mysqld.pid
socket=/var/run/mysqld/mysqld.sock
port=3306
basedir=/usr
datadir=/var/lib/mysql
tmpdir=/tmp
lc-messages-dir=/usr/share/mysql
log_error=/var/log/mysql/error.log
max_connections=200
max_user_connections=30
wait_timeout=30
interactive_timeout=50
long_query_time=5
innodb_file_per_table
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

!includedir /etc/mysql/conf.d/
57
Loki

character_set_client, _connection et _results doivent tous être utf8mb4 pour que ce gâteau soit mangeable.

Quelque chose, quelque part, définit un sous-ensemble de ceux individuellement. Fouiller dans les paramètres de my.cnf et phpmyadmin - quelque chose ne se règle pas tous les trois.

Si SET NAMES utf8mb4 est exécuté, les trois sont correctement définis.

Le soleil brillait parce que ce n’est que 3 octets - E2 98 80; utf8 est suffisant pour les codages utf8 à 3 octets de caractères Unicode.

66
Rick James

Il est probable que votre service/application se connecte avec "utf8" au lieu de "utf8mb4" pour le jeu de caractères du client. Cela dépend de l'application cliente.

Pour une application PHP, voir http://php.net/manual/en/function.mysql-set-charset.php ou http://php.net/manual/en/mysqli .set-charset.php

Pour une application Python, voir https://github.com/PyMySQL/PyMySQL#example ou http://docs.sqlalchemy.org/en/latest/dialects/mysql.html#mysql-unicode

Vérifiez également que vos colonnes sont bien utf8mb4. Un moyen direct est comme ça:

mysql> SELECT character_set_name FROM information_schema.`COLUMNS`  WHERE table_name = "user"   AND column_name = "displayname";
+--------------------+
| character_set_name |
+--------------------+
| utf8mb4            |
+--------------------+
1 row in set (0.00 sec)
6
Pierce

Pour moi, il s’est avéré que le problème se trouvait dans le client mysql.

le client mysql met à jour le paramètre de caractère de my.cnf sur un serveur et a entraîné un paramètre de caractère non souhaité.

Donc, ce que je devais faire, c'est simplement ajouter character-set-client-handshake = FALSE. Il empêche les paramètres du client de perturber les paramètres de mon personnage.

my.cnf serait comme ceci.

[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
...

J'espère que ça aide.

5
user3624198

ALTER TABLE table_name MODIFIER column_namecolumn_name VARCHAR (255) JEU DE CARACTERES utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL;

exemple de requête:

ALTER TABLE `reactions` CHANGE `emoji` `emoji` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL;

enter image description here

après cela, réussi à stocker emoji dans la table:

enter image description here

0
Saurabh Mistry