PHP / MySQL con problemas de encoding

Estoy teniendo problemas con PHP con respecto a la encoding.

Tengo una página JavaScript / jQuery HTML5 que interactúa con mi script PHP usando $ .post. Sin embargo, PHP se enfrenta a un problema extraño, probablemente relacionado con la encoding.

Cuando yo escribo

htmlentities("í") 

Espero PHP a la salida í . Sin embargo, en su lugar produce í Al principio, pensé que estaba cometiendo un error con las codificaciones, sin embargo

 htmlentities("í")=="í"?"Good":"Fail"; 

está produciendo “Fail”, donde

 htmlentities("í")=="í"?"Good":"Fail"; 

Pero htmlentities($search, null, "utf-8") funciona como se esperaba.

Quiero que PHP se comunique con un servidor MySQL, pero también tiene problemas de encoding, incluso si uso utf8_encode. ¿Que debería hacer?

EDITAR: en el comando SQL, escribiendo

 SELECT id,uid,type,value FROM users,profile WHERE uid=id AND type='name' AND value='XXX'; 

donde XXX no contiene í caracteres, funciona como se esperaba, pero no ocurre si hay un carácter “í”.

 SET NAMES 'utf8'; SET CHARACTER SET 'utf8'; SELECT id,uid,type,value FROM users,profile WHERE uid=id AND type='name' AND value='XXX'; 

No solo falla para í caracteres, sino que también falla para cadenas sin ningún carácter “especial”. Quitar los ‘caracteres de SET NAMES y SET CHARACTER SET no parece cambiar nada.

Me estoy conectando a la base de datos MySQL usando PDO.

EDIT 2: Estoy usando MySQL versión 5.1.30 de XAMPP para Linux.

EDIT 3: Ejecutando SHOW VARIABLES LIKE '%character%' desde salidas PhpMyAdmin

 character_set_client utf8 character_set_connection utf8 character_set_database latin1 character_set_filesystem binary character_set_results utf8 character_set_server latin1 character_set_system utf8 character_sets_dir /opt/lampp/share/mysql/charsets/ 

Ejecutando la misma consulta desde mi script PHP (con print_r) resultados:

 Array ( [0] => Array ( [Variable_name] => character_set_client [0] => character_set_client [Value] => latin1 [1] => latin1 ) [1] => Array ( [Variable_name] => character_set_connection [0] => character_set_connection [Value] => latin1 [1] => latin1 ) [2] => Array ( [Variable_name] => character_set_database [0] => character_set_database [Value] => latin1 [1] => latin1 ) [3] => Array ( [Variable_name] => character_set_filesystem [0] => character_set_filesystem [Value] => binary [1] => binary ) [4] => Array ( [Variable_name] => character_set_results [0] => character_set_results [Value] => latin1 [1] => latin1 ) [5] => Array ( [Variable_name] => character_set_server [0] => character_set_server [Value] => latin1 [1] => latin1 ) [6] => Array ( [Variable_name] => character_set_system [0] => character_set_system [Value] => utf8 [1] => utf8 ) [7] => Array ( [Variable_name] => character_sets_dir [0] => character_sets_dir [Value] => /opt/lampp/share/mysql/charsets/ [1] => /opt/lampp/share/mysql/charsets/ ) ) 

Corriendo

 SET NAMES 'utf8'; SET CHARACTER SET 'utf8'; SHOW VARIABLES LIKE '%character%' 

saca una matriz vacía.

Es muy importante especificar la encoding de htmlentities para que coincida con la de la entrada, como lo hizo en su ejemplo final, pero se omite en los primeros tres.

 htmlentities($text,ENT_COMPAT,'utf-8'); 

En cuanto a las comunicaciones con MySQL, debe asegurarse de que la intercalación de la conexión y el conjunto de caracteres coinciden con los datos que está transmitiendo. Puede configurar esto en el archivo de configuración o en tiempo de ejecución mediante las siguientes consultas:

 SET NAMES utf8; SET CHARACTER SET utf8; 

Asegúrese de que la tabla, la base de datos y los juegos de caracteres del servidor coincidan también. Hay una configuración que no puede cambiar en el tiempo de ejecución, y ese es el conjunto de caracteres del servidor. Debe modificarlo en el archivo de configuración:

 [mysqld] character-set-server = utf8 default-character-set = utf8 skip-character-set-client-handshake 

Lea más sobre conjuntos de caracteres y colaciones en MySQL en el manual .

Renacimiento tardío. Pero para mayor referencia aquí hay algunos consejos adicionales:

  1. Use mysql_set_charset en lugar de SET xxx
  2. Asegúrese de guardar el archivo con encoding UTF-8 (esto a menudo se pasa por alto)
  3. Establecer encabezados:

  4. Si la configuración de su servidor Apache contiene una directiva AddDefaultCharset con una encoding diferente, grítele a su administrador de host.

Me encontré con este problema. Tengo todo el contenido de un sitio web en español, con todos los caracteres especiales que puede esperar (áéíóúñ) y sus versiones en mayúscula.

En mi caso, fue una inconsistencia con el juego de caracteres / colación del servidor. Todo lo demás estaba configurado en utf8, pero el juego de caracteres del servidor, que tenía latin1. Esto causó que todos los datos utf8 ingresados ​​en la base de datos se muestren en su forma codificada en bruto, como L í equivaldría a A con tilde ~ …

Estoy usando mysqli, y para solucionarlo, hice uso del método explicado anteriormente por Anthony Accioly (usando mysql_set_charset). Dicho método tiene una versión mysqli y eso es lo que usé.

Después de eso, estaba desconcertado. Todavía tengo un lío cuando veo mi sitio web. Por supuesto, no sabía que al cambiar ese latin1 por utf8 también estropearía el codificador / decodificador de todo el asunto. Así que utilicé la ayuda de un codificador / decodificador de cadenas en línea para arreglar los datos de mi tabla.

Realicé varias exportaciones de todos mis datos de contenido (puede configurarlos para obtener consultas de actualización y eso será más rápido para su proceso de actualización) y ejecutar la salida sql a través del codificador / decodificador en línea antes mencionado, luego copie pegar las consultas corregidas en phpmyadmin sql panel … arreglando así mis errores de encoding. Ahora todo es como debe ser, Y puedo volver a procesar búsquedas con pérdidas: María, María, María, María coincidirán con María, María, etc. Todos los personajes agudos evalúan su carácter de vocal básica. Victoria épica.