2016-02-01 1 views
41

J'essaie de sauvegarder les noms des utilisateurs d'un service dans ma base de données MySQL. Ces noms peuvent contenir des emojis comme (juste pour des exemples)MySQL utf8mb4, Erreurs lors de la sauvegarde des Emojis

Après une recherche un peu j'ai trouvé ce stackoverflow liant à ce tutorial. J'ai suivi les étapes et il semble que tout est configuré correctement.

J'ai une base de données (charset et collation définie sur utf8mb4 (_unicode_ci)), une table appelée TestTable, également configurée de cette façon, ainsi qu'une colonne "Text" configurée de cette façon (VARCHAR (191) utf8mb4_unicode_ci).

Lorsque je tente de sauver emojis je reçois une erreur:

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 bien le soleil était ☀️

Bien que je n'ai pas essayé tous pour être honnête.

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

Veuillez noter: Tous les tests de sauvegarde n'impliquaient pas un côté client. J'utilise phpmyadmin pour changer manuellement les valeurs et sauvegarder les données. Donc, la configuration correcte du côté client est quelque chose que je vais prendre en charge après le serveur enregistre correctement emojis.

Une autre Sidenote: Actuellement, lors de l'enregistrement emojis je soit obtenir l'erreur comme ci-dessus, ou aucune erreur et les données de Username seront stockées sous forme Username ????. Erreur ou aucune erreur dépend de la façon dont je sauvegarde. Lors de la création/sauvegarde via SQL Statement je sauvegarde avec des points d'interrogation, lors de l'édition en ligne je sauvegarde avec des points d'interrogation, lors de l'édition en utilisant le bouton d'édition je reçois l'erreur.

merci

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

Quand je suis connecté en tant que root sur mon serveur et lu 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 semble comme le suivant:

+--------------------------+--------------------+ 
| 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, je reçois le second en tant que paramètres.

** 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/ 
+1

C'est un problème de phpmyadmin, essayez d'autres clients mysql. – jsxqf

+2

Je ne pense pas que ce soit un problème de phpmyadmin. Comme vous pouvez le voir dans Edit1, je pense qu'il y a une mauvaise configuration entre les variables/paramètres conf/default et ceux de la base de données. Même si lors de la création d'une nouvelle base de données. – Loki

+0

Qu'est-ce que '$ cfg [" DefaultCharset "]' dans votre configuration PMA? – miken32

Répondre

37

character_set_client, _connection et _results doivent tous être utf8mb4 pour cette shortcake être mangeable.

Quelque chose, quelque part, en définit un sous-ensemble individuellement. Fouillez les paramètres de my.cnf et de phpmyadmin - quelque chose ne se passe pas tous les trois.

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

Le soleil a brillé parce qu'il est seulement 3-bytes - E2 98 80; utf8 est suffisant pour les encodages utf8 de 3 octets de caractères Unicode.

+0

Très bien, je pense que cela me rapproche. Je vous remercie. J'ai édité ma question et ajouté le my.cnf. Peut-être que vous pouvez voir quelque chose là-dedans? – Loki

+1

La connexion doit avoir 'utf8mb4'. Si vous ne trouvez pas où faire cela, exécutez 'SET NAMES utf8mb4'. –

+0

Ceci est une bonne explication de ce qui s'est mal passé. Mais en plus j'ai dû vérifier la session et les variables globales. Réaliser PHPMyadmins Les variables de session étaient toujours incorrectes et l'erreur se produisait uniquement pour le tableau d'administration. – Loki

3

Il est probable que votre service/application se connecte avec "utf8" au lieu de "utf8mb4" pour le jeu de caractères client. C'est à l'application client.

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

En outre, vérifiez que vos colonnes sont vraiment utf8mb4. Une manière directe est comme ceci:

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) 
4

Pour moi, il s'est avéré que le problème a menti dans le client mysql. Mysql client met à jour my.cnf le paramétrage de caractère sur un serveur, et il en résulte un réglage de caractère non intentionnel. Donc, ce que je devais faire est d'ajouter character-set-client-handshake = FALSE. Il empêche les paramètres du client de perturber mon réglage de caractère.

my.cnf serait comme ceci.

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

Espérons que cela aide.