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:
- Establezca la codificación interna de PHP en UTF-8.
- Guarde todos sus archivos de origen como UTF-8.
- Use UTF-8 como codificación de salida (no olvide enviar
Content-type
encabezados adecuados ).
- Configure la conexión de la base de datos para usar UTF-8 (
SET NAMES UTF8
en MySQL).
- Configure todo lo demás para que sea UTF-8 si es posible.
- Para cualquier cosa que no pueda controlar (por ejemplo, servicios web de terceros), asegúrese de conocer la codificación, y convertir a UTF-8 lo antes posible, y volver a la otra codificación lo más tarde posible.
¿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 llama echo $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:
$original = "शक्नोम्यत्तुम्";
echo strlen($original);
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.