No se puede almacenar emoji en la base de datos

LA SITUACIÓN :

Lo siento de antemano si esta pregunta ya se ha hecho, pero las soluciones no funcionan para mí.

No importa lo que intente, no puedo almacenar emoji en mi base de datos. Se guardan como ???? .
Los únicos emojis que se guardan correctamente son los que requieren sólo 3 bytes, como la cara tímida o el sol.

El utf8mb4 real no está funcionando.

Imagen de la base de datos

Se ha probado tanto en Android como en Ios. Con los mismos resultados.

VERSIONES :

Mysql: 5.5.49
CodeIgniter: 3.0.0

LOS PASOS :

  1. He modificado el conjunto de caracteres de base de datos y propiedades de intercalación.

    ALTER DATABASE my_database CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci

  2. He modificado el conjunto de caracteres de tabla y las propiedades de intercalación.

    ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci

  3. He establecido cada campo de la tabla, cuando sea posible, como Codificación: UTF-8(ut8mb4) y Colación: utf8mb4_unicode_ci

  4. He modificado la conexión de la base de datos en la aplicación CodeIgniter.

  5. He ejecutado el siguiente: SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci

  6. Por último también he intentado esto: REPAIR TABLE table_name; OPTIMIZE TABLE table_name; REPAIR TABLE table_name; OPTIMIZE TABLE table_name;

Todo debería haber sido configurado correctamente, pero aún así no funciona.

AJUSTES DE BASE DE DATOS :

Este es el resultado ejecutando el siguiente comando:

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

Configuración de la base de datos

AJUSTES DE LA MESA :

Un screeshot de la estructura de la mesa:

Configuración de la tabla

CONEXIÓN DE BASE DE DATOS :

Estas son las configuraciones de conexión a la base de datos dentro de database.php (note que esta no es la única base de datos, también hay otras que se conectan usando 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 ); 

CONFIGURACIONES MY.CNF :

Este es el contenido completo del archivo 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 

LA PREGUNTA :

¿Sabes por qué no funciona? ¿Me estoy perdiendo de algo?

HIPOTESIS 1 :

No estoy seguro, pero la causa del problema puede ser esta:

Como se puede ver en my.cnf character-set-server se establece claramente como utf8mb4 :

Pero después de ejecutar la consulta en la base de datos:

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

El resultado es que character-set-server = latin1

¿Sabes por qué es eso? ¿Por qué no se está actualizando?

HIPOTESIS 2 :

La aplicación utiliza varias bases de datos diferentes. Este se establece en utf8mb4, pero todos los demás se establecen en utf8. Puede ser un problema incluso si son bases de datos separadas?

¡Gracias!

EDITAR:

Este es el resultado de 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:

He ejecutado el siguiente comando:

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

Y otros dos similares con 😂 y 👻

Se insertaban en la mesa sin problemas:

Introduzca aquí la descripción de la imagen

Pero en la aplicación real lo que realmente veo es ? (esta vez sólo uno? y no 4)

La única manera que sé de conseguir ???? para un Emoji es no tener la columna declarada utf8mb4 . Entiendo que aparentemente ha determinado que la columna está declarada de esa manera, pero por favor ejecute SHOW CREATE TABLE table_name; para confirmarlo.

El valor predeterminado del sistema, el valor predeterminado de la base de datos y el valor por omisión de la tabla son irrelevantes si la columna reemplaza al conjunto de CHARACTER SET .

Una nota a todos los otros intentos de respuestas: El COLLATION es irrelevante, sólo el CHARACTER SET es relevante para esta pregunta .

my.cnf se carga primero, luego conf.d/*.cnf .

En lugar de modificar my.cnf * (que puede ser sobrescrita por configuraciones en conf.d/*.cnf ), cree una configuración de sustitución personalizada, por ejemplo, conf.d/90-my.cnf .

El prefijo 90 garantiza que los ajustes personalizados se carguen por último, lo que significa que sobreescriben cualquier configuración anterior.

Para asegurarse de que se vuelve a cargar la nueva configuración, consulte Recargar sin reiniciar el servicio MySQL .

Ejemplo de estructura de configuración (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 

Bueno, finalmente me las arreglé para hacerlo funcionar! Gracias a todos los que intentaron ayudarme, especialmente @Rick James y @Gerard Roche.

SUGERENCIA:

Si necesita trabajar con emoji en primer lugar hacer pruebas simples en localhost. Cree una nueva base de datos y haga una nueva aplicación para fines de prueba.

Si sigues los pasos que escribí en la pregunta o si sigues este tutorial: https://mathiasbynens.be/notes/mysql-utf8mb4#utf8-to-utf8mb4 debe funcionar.

Trabajando localmente en una nueva aplicación básica tendrás más control y más espacio para hacer todas las pruebas que necesites.

SOLUCIÓN:

En mi caso el problema estaba en la configuración de la base de datos en CodeIgniter. No estaba configurando adecuadamente el char_set y la colación para una estúpida visión: Estaba anulando la configuración de la base de datos en la función que guardaba mensajes para estar seguro de que estaba trabajando con la base de datos móvil.

ANTES DE:

 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 } 

DESPUÉS:

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

CONCLUSIÓN:

La aplicación debe establecer la conexión a la base de datos correctamente. Si tiene la base de datos correctamente configurada pero no establece la conexión correcta con su aplicación, no funcionará.

Así que si usted encuentra problemas similares asegúrese de que la api correctamente configurar el char_set como utf8mb4 y db_collat como utf8mb4_unicode_ci .

En lugar de varchar, puede cambiar el valor de la tabla archivada como se indica a utf8mb4

Asegúrese de que todos los conjuntos de caracteres y campos de texto por defecto de sus tablas se conviertan en utf8mb4, además de establecer los conjuntos de caracteres de cliente y servidor, por ejemplo ALTER TABLE mytable charset=utf8mb4, MODIFY COLUMN textfield1 VARCHAR(255) CHARACTER SET utf8mb4,MODIFY COLUMN textfield2 VARCHAR(255) CHARACTER SET utf8mb4; y así.

hola he utilizado EMOJI en android y lo almacené en la base de datos orm utilizando EMOJI_INDEX . He guardado en db en el mensaje normal en forma de cadena, pero cuando me sale ese tiempo comprobar si hay cualquier emoji luego convertirlo en procesemoji.

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

Echa un vistazo desde aquí cómo cambié Emoji_Index a proceso

 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); } } 

Para más información echa un vistazo desde aquí . Gracias, espero que esto te ayude.

Tuve un problema con la versión del servidor, en linux. Tuve que cambiar el archivo database_interface.lib.php manualmente y alrededor de este

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

cambiarlo de modo que, se convierta en esto: (anote las referencias 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 ); } } 

Respuesta actualizada

Puede intentar charset utf8 collation utf8_unicode_ci lugar de utf8mb4_unicode_ci .

ejecutar esta consulta

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

old answer Debe utilizar collation utf8mb4_bin lugar de utf8mb4_unicode_ci .

ejecutar esta consulta

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

Emojis se almacenará como código y se convertirá en emojis de nuevo en Android y aplicaciones de iOS. He utilizado este código en mis proyectos también.

  • El inicio de sesión de Android con el objeto json está vacío en la búsqueda incluso si la ejecución de archivos php en el navegador Chrome está bien
  • ¿Existe un equivalente de ucwords en java?
  • Cómo hacer push notificación de android de php
  • Cuando se llama a un archivo php con algún código js de android, el código js es la salida de una llamada
  • Cargar archivos de android (java) a un servidor mediante PHP
  • Servidor Android y PHP: cifrar y descifrar datos
  • Codificación PHP en Android
  • Enviar un objeto JSON de Android a servidor PHP con el método POST y HttpURLConnection
  • Obtener imágenes de un servidor PHP a Android
  • ¿Cómo detectar si un dispositivo móvil es emulado por Google Chrome?
  • Escritorio remoto basado en web para conectarse a android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.