UTF8?
UTF16?
¿Las cadenas en PHP también hacen un seguimiento de la codificación utilizada?
Veamos este script por ejemplo. Digamos que corro:
$original = "शक्नोम्यत्तुम्";
¿Qué pasa realmente?
Obviamente, creo $original
que no contendrá solo 7 caracteres. Esos glifos deben estar representados por varios bytes allí.
Entonces lo hago:
$converted = mb_convert_encoding ($original , "UTF-8");
¿Qué va a pasar $converted
? ¿Cómo será $converted
diferente de $original
?
¿Será exactamente la misma secuencia de bytes $original
pero con una codificación diferente?
Respuestas:
Una cadena PHP es solo una secuencia de bytes, sin codificación alguna. Los valores de cadena pueden provenir de varias fuentes: el cliente (a través de HTTP), una base de datos, un archivo o literales de cadena en su código fuente. PHP lee todo esto como secuencias de bytes, y nunca extrae ninguna información de codificación.
Siempre que todas sus fuentes de datos y destinos usen la misma codificación, lo peor que puede suceder es que las posiciones de las cadenas sean incorrectas (si usa codificaciones de varios bytes), ya que PHP contará bytes, no caracteres.
Pero si las codificaciones no coinciden (por ejemplo, escribe un literal de cadena en un archivo fuente almacenado como UTF-8 y luego lo envía a una base de datos que espera Latin-1), PHP no realizará ninguna conversión por usted: lo hará felizmente copie los bytes en bruto.
La solución más sensata es esta:
Content-type
encabezados adecuados ).SET NAMES UTF8
en MySQL).¿Por qué UTF-8? Debido a que puede representar todos los caracteres Unicode y, por lo tanto, reemplaza todas las codificaciones existentes de 7 y 8 bits, y debido a que es binariamente compatible con ASCII, es decir, cada cadena ASCII válida también es una cadena UTF-8 válida (pero no vv .).
En su ejemplo, lo que sucede es esto.
Primero, guarde su archivo fuente; su editor de texto probablemente esté configurado para usar UTF-8, por lo que su literal de cadena termina codificado en UTF-8 en el disco. PHP lee este archivo, interpretando la cadena como una serie de bytes;
$original
ahora contiene una cadena codificada UTF-8 de 7 caracteres, que es solo una secuencia de bytes (aunque contiene más de 7 bytes, porque cada carácter está representado por dos o más bytes). Si luego llamaecho $original
, la cadena codificada se envía al cliente tal cual; Si le ha dicho al cliente que espere UTF-8, todo está bien, pero si no lo ha hecho, PHP no tiene forma de notar la diferencia, y terminará con basura en el navegador. Como experimento, prueba esto:strlen
es independiente de la codificación y asume una codificación de 8 bits de ancho fijo, es decir, un byte por carácter, por lo que contará bytes, no caracteres.fuente