En primer lugar, debe entender que un personaje con un signo diacrítico como ó o î (de su ejemplo) no es automáticamente un "carácter utf-8". Es simplemente un carácter que tiene diferentes codificaciones (si las hay) en diferentes conjuntos de caracteres, incluso en aquellos conjuntos de caracteres que tienen en común la parte básica ASCII de un solo byte (es decir, el alfabeto inglés, los dígitos, la puntuación más común y un poco mas). Podría llamarlo un "personaje problemático", pero no un "personaje utf-8".
Por lo tanto, cuando escribió su pie de página <div>
, NO lo escribió codificado en UTF-8. Su editor guardó esos caracteres en una codificación de un solo byte, como ISO 8859-1 o uno de sus parientes.
Los navegadores normalmente detectan automáticamente la codificación utilizada en una página, si no está especificada. Es por eso que inicialmente fue capaz de ver en el navegador exactamente lo que había escrito en su editor.
Luego ha intentado iniciar sesión con un "carácter problemático" en el nombre de usuario. El navegador ha interpretado que su página tiene una codificación de un solo byte, por lo que ha codificado la entrada de su formulario de la misma manera y lo envía de vuelta codificado en un solo byte al servidor. El código PHP no se había escrito teniendo en cuenta esta posibilidad, al parecer, porque no configuraba correctamente el tercer parámetro de htmlspecialchars()
, que es "UTF-8"
de forma predeterminada (a partir de PHP 5.4.0 - anteriormente era "ISO-8859-1"
). Como una cadena codificada de un solo byte con "caracteres problemáticos" casi nunca es una cadena UTF-8 válida (vea mi comentario a su pregunta, es el segundo comentario), htmlspecialchars() lo rechazó.
A continuación, agregó correctamente el header('Content-Type: text/html; charset=utf-8');
, que deshabilitó la detección automática de juego de caracteres por el navegador. En este punto, se hizo evidente que su archivo con el pie de página <div>
no estaba codificado en UTF-8 (consulte de nuevo mi comentario para obtener una explicación de los signos de interrogación que aparecen en lugar de los "caracteres problemáticos").
Así que todo lo que queda por hacer es convencer a su editor de que guarde los archivos codificados en UTF-8. Como otros han notado, guardar el archivo en una codificación diferente no funciona en todos los editores. Comenzar a partir de un archivo nuevo a veces es la solución, tal vez después de haber configurado la codificación predeterminada de su editor en UTF-8.
Para verificar la codificación, puede usar el comando file
en un intérprete de comandos. Su salida debe ser algo como
main.php: PHP script, UTF-8 Unicode text
O de lo contrario, podría utilizar el comando od -tx1z
, que vuelca su archivo (tal vez | less
), como una secuencia de bytes hexadecimales con la cadena correspondiente en el lado. Si el archivo está codificado de un solo byte, sus "caracteres problemáticos" serán bytes únicos> = 0x80. Si está codificado en UTF-8, serán secuencias de 2 bytes (otros serán 3 o más bytes), todos> = 0x80, mientras que los "caracteres no problemáticos" continuarán siendo bytes únicos < 0x80.
El artículo que menciona parece estar bien escrito, simplemente sígalo.
que no es necesario la directiva AddDefaultCharset
en el archivo .htaccess
, sin embargo, si todas sus páginas se generan con la cabecera HTTP Content-Type: text/html; charset=utf-8
, debido a que el efecto de la directiva de Apache es exactamente el mismo (y es bueno para mantener el control en la codificación dentro de PHP).
Agregar el <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
tiene el mismo efecto, para el navegador, que el encabezado HTTP anterior (tenga en cuenta el http- equiv). El encabezado HTTP es más limpio, pero esta metaetiqueta adicional puede ayudar en caso de que una página se guarde sin la información del encabezado.
Lo más importante, no tengas miedo de UTF-8, ¡porque es tu amigo!
(... pero, a partir de la respuesta que obtuvo su recompensa, veo que, como muchas personas, sigue pensando que la comprensión de la codificación de caracteres es demasiado difícil para ti ☹)
Estoy teniendo el mismo problema. ¿Encontraste alguna solución? – coderama
esos signos de interrogación son el resultado de secuencias de bytes UTF-8 no válidas. Lo más probable es que esté usando un editor que guardó texto en una codificación de un solo byte, como, por ejemplo, [ISO 8859-1] (http://en.wikipedia.org/wiki/ISO/IEC_8859-1). En todas las codificaciones de un solo byte que son extensiones de ASCII, la parte extendida tiene valores de bytes> = 128. Todos los caracteres de un solo byte de UTF-8 son <128, todos los caracteres de varios bytes consisten en bytes> = 128. Por eso Los caracteres ISO 8859-x con signos diacríticos se convierten en signos de interrogación: nunca podrían ser válidos UTF-8, excepto en combinaciones poco probables. –