Uma string PHP é apenas uma sequência de bytes, sem nenhuma codificação marcada para ela. Os valores da string podem vir de várias fontes: o cliente (por HTTP), um banco de dados, um arquivo ou de literais da string no seu código-fonte. O PHP lê tudo isso como sequências de bytes e nunca extrai nenhuma informação de codificação.
Desde que todas as suas fontes e destinos de dados usem a mesma codificação, a pior coisa que pode acontecer é que as posições das strings estejam incorretas (se você usar codificações de vários bytes), pois o PHP contará bytes, não caracteres.
Mas se as codificações não corresponderem (por exemplo, você escreve uma string literal em um arquivo de origem armazenado como UTF-8 e a envia para um banco de dados que espera o Latin-1), o PHP não fará nenhuma conversão para você: copie alegremente os bytes em bruto.
A solução mais segura é esta:
- Defina a codificação interna do PHP como UTF-8.
- Salve todos os seus arquivos de origem como UTF-8.
- Use UTF-8 como sua codificação de saída (não esqueça de enviar
Content-type
cabeçalhos adequados ).
- Defina a conexão com o banco de dados para usar UTF-8 (
SET NAMES UTF8
no MySQL).
- Configure todo o resto para ser UTF-8, se possível.
- Para qualquer coisa que você não possa controlar (por exemplo, serviços da web de terceiros), verifique a codificação e converta-a em UTF-8 o mais cedo possível, e volte para a outra codificação o mais tarde possível.
Por que UTF-8? Como ele pode representar todos os caracteres Unicode e, portanto, substitui todas as codificações de 7 e 8 bits existentes, e por ser binário compatível com ASCII, ou seja, toda string ASCII válida também é uma string UTF-8 válida (mas não vv .).
No seu exemplo, o que acontece é isso.
Primeiro, você salva seu arquivo de origem; seu editor de texto provavelmente está configurado para usar UTF-8, portanto, sua string literal termina em UTF-8 codificada no disco. O PHP lê esse arquivo, interpretando a string como uma série de bytes; $original
agora contém uma sequência codificada em UTF-8 de 7 caracteres, que é apenas uma sequência de bytes (embora contenha mais de 7 bytes, porque cada caractere é representado por dois ou mais bytes). Se você ligar echo $original
, a sequência codificada será enviada ao cliente como está; se você disse ao cliente que esperava UTF-8, está tudo bem, mas se não tiver, o PHP não tem como saber a diferença e você acabará com lixo no navegador. Como um experimento, tente o seguinte:
$original = "शक्नोम्यत्तुम्";
echo strlen($original);
strlen
é independente de codificação e assume uma codificação de 8 bits de largura fixa, ou seja, um byte por caractere, portanto, contará bytes, não caracteres.