MySQL utf8mb4, Errori durante il salvataggio di Emojis

Cerco di salvare i nomi degli utenti da un servizio nel mio database MySQL. Quei nomi possono contenere emoji come 🙈😂😱🍰 (solo per esempi)

Dopo aver cercato un po ‘ho trovato questo stackoverflow che collega a questo tutorial . Ho seguito i passaggi e sembra che tutto sia configurato correttamente.

Ho un Database (set di caratteri e regole di confronto su utf8mb4 (_unicode_ci)), una tabella denominata TestTable, anch’essa configurata in questo modo, così come una colonna “Testo”, configurata in questo modo (VARCHAR (191) utf8mb4_unicode_ci).

Quando provo a salvare gli emoji ricevo un errore:

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 

L’unico Emoji che ero in grado di salvare correttamente era il sole ☀️

    Sebbene non li abbia provati tutti per essere onesti.

    C’è qualcosa che mi manca nella configurazione?

    Nota: tutti i test di salvataggio non hanno riguardato il lato cliente. Io uso phpmyadmin per modificare manualmente i valori e salvare i dati. Quindi la corretta configurazione del lato client è qualcosa di cui mi prenderò cura dopo che il server ha salvato correttamente gli emoji.

    Un altro Sidenote : Attualmente, quando salvi gli emoji, o ottengo l’errore come sopra, o non ottengo alcun errore e i dati di Username 🍰 verranno memorizzati come Username ???? . Errore o nessun errore dipende dal modo in cui io salvo. Quando creo / salvando tramite istruzione SQL, salvi con i punti interrogativi, quando modifichi in linea salvi con i punti interrogativi, quando modifichi utilizzando il pulsante di modifica ottengo l’errore.

    grazie

    EDIT 1: Va bene, quindi penso di aver scoperto il problema, ma non la soluzione. Sembra che le variabili specifiche del database non siano cambiate correttamente.

    Quando ho effettuato l’accesso come root sul mio server e ho letto le variabili (globali):
    Query utilizzata: 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) 

    Per il mio Database (in phpmyadmin, la stessa query) sembra il seguente:

     +--------------------------+--------------------+ | 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 | +--------------------------+--------------------+ 

    Come posso regolare queste impostazioni sul database specifico? Anche se ho le prime impostazioni mostrate come predefinite, quando creo un nuovo database ottengo il secondo come impostazioni.

    Modifica 2:

    Ecco il mio file 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/ 

    character_set_client , _connection e _results devono essere tutti utf8mb4 per far utf8mb4 che la torta sia mangiabile.

    Qualcosa, da qualche parte, sta impostando un sottoinsieme di quelli individualmente. Rovistare tra le impostazioni di my.cnf e phpmyadmin: qualcosa non sta impostando tutti e tre.

    Se viene eseguito SET NAMES utf8mb4 , tutti e tre vengono impostati correttamente.

    Il sole splendeva perché è solo 3 byte – E2 98 80 ; utf8 è sufficiente per codifiche utf8 a 3 byte di caratteri Unicode.

    È probabile che il tuo servizio / applicazione si connetta con “utf8” anziché “utf8mb4” per il set di caratteri del cliente. Questo dipende dall’applicazione client.

    Per un’applicazione PHP vedi http://php.net/manual/en/function.mysql-set-charset.php o http://php.net/manual/en/mysqli.set-charset.php

    Per un’applicazione Python vedere https://github.com/PyMySQL/PyMySQL#example o http://docs.sqlalchemy.org/en/latest/dialects/mysql.html#mysql-unicode

    Inoltre, controlla che le tue colonne siano davvero utf8mb4. Un modo diretto è così:

     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) 

    Per me, si è scoperto che il problema si poneva nel client mysql.

    mysql client aggiorna l’impostazione char di my.cnf su un server e ha come risultato l’impostazione non intenzionale dei caratteri.

    Quindi, quello che dovevo fare è solo aggiungere character-set-client-handshake = FALSE . Disabilita le impostazioni del client disturbando le impostazioni del mio char.

    my.cnf sarebbe come questo.

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

    Spero che sia d’aiuto.