elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Rompecabezas de Bitcoin, Medio millón USD en premios


+  Foro de elhacker.net
|-+  Programación
| |-+  Desarrollo Web
| | |-+  PHP (Moderador: #!drvy)
| | | |-+  problema de codificación entre mysql y php
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: problema de codificación entre mysql y php  (Leído 4,286 veces)
gAb1


Desconectado Desconectado

Mensajes: 731


Ver Perfil
problema de codificación entre mysql y php
« en: 27 Abril 2016, 18:11 pm »

Estoy empezando a migrar (en mysql) de utf8 a utf8mb4 y a la hora de que php muestre contenido con caracteres especiales/acentuados, estos son remplazados por una interrogación con fondo negro ( � ).

Me he asegurado de que todo esté correcto. La base de datos está usando utf8mb4 (todas las tables y columnas con tipo: text, varchar, etc). Los archivos .php todos usan utf-8 (trabajo con visual studio code y esto es por defecto) y los headers, tanto en php como en html, están puestos a utf8.

Despues de instanciar mysqli, cambio el charset de utf8 a utf8mb4:

Código
  1. $mysqli->set_charset('utf8mb4');

Pero si lo dejo en utf8 todo funciona correcto... Y por lo que he estado leyendo, eso no tiene sentido alguno... Ya que en php, la codificación utf8 es completa y soporta hasta 4 bytes pero en mysql utf8 solo soporta hasta 3, por eso si el charset es utf8 pero mysql trabaja con utf8mb4 tiene que hacer conversión y es una perdida de tiempo...

¿Donde creeis que puede estar el problema?


En línea

MinusFour
Moderador Global
***
Desconectado Desconectado

Mensajes: 5.529


I'm fourth.


Ver Perfil WWW
Re: problema de codificación entre mysql y php
« Respuesta #1 en: 29 Abril 2016, 20:35 pm »

¿Que caracteres son remplazados por �? Ejemplos porfavor.


En línea

gAb1


Desconectado Desconectado

Mensajes: 731


Ver Perfil
Re: problema de codificación entre mysql y php
« Respuesta #2 en: 29 Abril 2016, 22:35 pm »

Los caracteres acentuados y demás especiales. Voy a explicarlo mejor:

Si utilizo: $mysqli->set_charset('utf8'); esto es lo que pasa:

- Los datos se guardan tal cual, por ejemplo si inserto Altaïr se guarda tal cual y cuando lo cojo con un select se muestra tal cual (el hex es 41 6C 74 61 C3AF 72).

Si utilizo $mysqli->set_charset('utf8mb4'); esto es lo que pasa:

- Los datos se guardan mal codificados, por ejemplo si inserto Altaïr esto es lo que se guarda Altaïr (el hex es 41 6C 74 61 C383C2AF 72) pero cuando hago el select es codificado y mostrado correctamente.

- Si guardo manualmente Altaïr en la columna, se muestra la interrogación con fondo negro: Alta�r (que es lo que pasa con todos los nombres de ciudades/zonas que tienen acentos).

Tengo una función de una clase que, por una razón desconocida, cuando está utf8mb4 en mysqli, los datos acentuados se muestran correctamente, pero si lo cambio a utf8, los datos que selecciona esta función son mostrados sin codificación utf8: por ejemplo, en la tabla "es" tengo Iniciar Sesión y si la codificación del mysqli es utf8 lo que se muestra es Iniciar Sesión, pero si la codificación del mysqli es utf8mb4 se muestra bien.

En resumen, si la codificación de mysqli es utf8, los datos son correctamente insertados y seleccionados en todas partes menos en la función de clase antes mencionada (que solo selecciona bien si esta utf8mb4).

Ahora bien, esta función de clase se encarga de detectar el idioma del navegador/cookie/configuración y selecciona datos de una tabla u otra, pasandole como parametro el código del texto. Esta función solo imprime bien si mysqli tiene utf8mb4....

Si necesitas ver tanto la clase loc_es o cualquier parte del código dimelo y lo puedo poner aquí si no es mucho o en un paste bin/etc.

Gracias!
En línea

MinusFour
Moderador Global
***
Desconectado Desconectado

Mensajes: 5.529


I'm fourth.


Ver Perfil WWW
Re: problema de codificación entre mysql y php
« Respuesta #3 en: 30 Abril 2016, 15:43 pm »

Es un caso de doble encoding:

C3 AF los está tomando como U+00C3 y U+00AF, que son:

Código:
ï

Respectivamente.

En lugar de hacer la conversión de C3 AF a U+00EF que es:

Código:
í

Realmente no tengo una explicación para:

Código:
Alta�r

Fuera de que quizás tu navegador lo ha insertado en la tabla como:

Código:
41 6C 74 61 EF 72

Cuando el navegador encuentra EF. Lo que hace en ese momento es contar los primeros bits hasta llegar a uno que sea 0. EF:

Código:
1110 1111

Esto significa que está esperando 3 bytes para producir un símbolo y cada byte después de eso necesita empezar con: 10xxxxxx. 0x72 en binario es:

Código:
0111 0010

No puede ser un byte de continuación, por lo que la producción esta mal formada. Sin mencionar que EF señala el inicio de una secuencia de 3 bytes (cuando solo tienes 2). Ahora lo que pienso que hace el navegador es simplemente remplazar el byte que no tiene sentido por el símbolo especial de remplazo.

¿Estás seguro que la tabla tiene formato utf8? En el primer caso, se está asumiendo que la conversión es de una codificación de un solo byte (ISO-8859-1, W-1252, etc) cuando la información realmente es UTF-8. Mientras que tu segundo caso se está asumiendo que la codificación es UTF-8 pero la información realmente es una codificación de un solo byte.
En línea

gAb1


Desconectado Desconectado

Mensajes: 731


Ver Perfil
Re: problema de codificación entre mysql y php
« Respuesta #4 en: 30 Abril 2016, 18:13 pm »

Las tablas tienen todas utf8mb4 y el collation es utf8mb4_unicode_ci.

Entonces es muy raro ya que en la tabla está almacenado con ï, pero cuando hago el select hex(name) from tabla; me muestra C3 AF....

Lo de la interrogación con fondo negro solo sale cuando mysqli tiene utf8mb4 y los datos están guardados tal cual en la tabla, entonces al mostrarlos, los acentos y demás caracteres son reemplazados.

Puede ser un problema del navegador (la cache o algo)?

EDITO: Haciendo un poco de debug me he encontrado con que mysqli no acepta utf8mb4.... la versión de php es 5.4.41 y mysql 5.5.41 (utf8mb4 se introdujo en 5.5.3).

Código
  1. $mysqli = new mysqli('127.0.0.1', 'user', 'pwd', 'db_name');
  2. $mysqli->set_charset('utf8mb4');
  3. printf("Current character set: %s\n", mysqli_character_set_name($mysqli));

Dice "latin1"... Si quito mb4 dice "utf8"...
« Última modificación: 30 Abril 2016, 20:06 pm por gAb1 » En línea

MinusFour
Moderador Global
***
Desconectado Desconectado

Mensajes: 5.529


I'm fourth.


Ver Perfil WWW
Re: problema de codificación entre mysql y php
« Respuesta #5 en: 30 Abril 2016, 23:33 pm »

Huh, eso es interesante. Prueba con:

Código
  1. $mysqli->query("SET NAMES 'utf8mb4'");

Justo después de usar set_charset con 'utf8' (a secas).
En línea

gAb1


Desconectado Desconectado

Mensajes: 731


Ver Perfil
Re: problema de codificación entre mysql y php
« Respuesta #6 en: 1 Mayo 2016, 00:59 am »

Dice lo mismo. ¿Crees que puede ser una configuración de php? Seguro que no es nada... sin embargo ya van dos dias perdidos buscando una solución  :-(

Gracias!
En línea

MinusFour
Moderador Global
***
Desconectado Desconectado

Mensajes: 5.529


I'm fourth.


Ver Perfil WWW
Re: problema de codificación entre mysql y php
« Respuesta #7 en: 1 Mayo 2016, 04:03 am »

Lo más probable es que si sea una cosa de PHP. Prueba a hacer la query anterior y usa esta otra para verificar que valores te arroja:

Código
  1. SHOW VARIABLES LIKE 'character_set%';

Si puedes, prueba las consultas desde otro cliente SQL (como desde la terminal).
En línea

gAb1


Desconectado Desconectado

Mensajes: 731


Ver Perfil
Re: problema de codificación entre mysql y php
« Respuesta #8 en: 1 Mayo 2016, 04:48 am »

Arg! Ultimamente estoy espeso.... con lo facil que habria sido comprobar el error del mysqli....

Código
  1. echo $mysqli->error;

Citar
Can't initialize character set utf8mb4 (path: /usr/share/mysql/charsets/)

Código
  1. +--------------------------+----------------------------+
  2. | Variable_name            | Value                      |
  3. +--------------------------+----------------------------+
  4. | character_set_client     | utf8                       |
  5. | character_set_connection | utf8                       |
  6. | character_set_database   | utf8mb4                    |
  7. | character_set_filesystem | binary                     |
  8. | character_set_results    | utf8                       |
  9. | character_set_server     | latin1                     |
  10. | character_set_system     | utf8                       |
  11. | character_sets_dir       | /usr/share/mysql/charsets/ |
  12. +--------------------------+----------------------------+
  13. 8 rows in set (0.00 sec)

Ya le dije a mi amigo que es el que tiene acceso ssh que lo solucione.

Gracias!
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
[PROBLEMA] Ayuda con codificacion
Programación C/C++
SonaArtica 1 1,970 Último mensaje 25 Abril 2012, 17:54 pm
por xiruko
Codificación base de datos mysql
Desarrollo Web
Zitros 2 1,911 Último mensaje 31 Agosto 2013, 07:01 am
por Zitros
Problema de codificacion
PHP
octavioxd 3 1,894 Último mensaje 27 Noviembre 2014, 15:59 pm
por MinusFour
Problema codificación Linux
GNU/Linux
robebugaty 0 1,619 Último mensaje 10 Mayo 2015, 19:32 pm
por robebugaty
Problema con la codificación utf-8
Scripting
Avispon99 1 2,306 Último mensaje 3 Marzo 2018, 07:46 am
por Eleкtro
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines