Una stringa PHP è solo una sequenza di byte, senza codifica taggata in alcun modo. I valori di stringa possono provenire da varie fonti: il client (su HTTP), un database, un file o letterali di stringa nel codice sorgente. PHP legge tutte queste come sequenze di byte e non estrae mai alcuna informazione di codifica.
Finché tutte le origini dati e le destinazioni utilizzano la stessa codifica, la cosa peggiore che può accadere è che le posizioni delle stringhe siano errate (se si utilizzano codifiche multi-byte), poiché PHP conterà i byte, non i caratteri.
Ma se le codifiche non corrispondono (ad esempio scrivi una stringa letterale in un file sorgente memorizzato come UTF-8 e poi lo invii a un database che prevede Latin-1), PHP non eseguirà alcuna conversione per te: lo farà copi felicemente i byte su raw.
La soluzione più sana è questa:
- Imposta la codifica interna di PHP su UTF-8.
- Salva tutti i tuoi file sorgente come UTF-8.
- Usa UTF-8 come codifica di output (non dimenticare di inviare le
Content-type
intestazioni adatte ).
- Impostare la connessione al database per utilizzare UTF-8 (
SET NAMES UTF8
in MySQL).
- Configura tutto il resto per essere UTF-8 se possibile.
- Per tutto ciò che non puoi controllare (ad es. Servizi Web di terze parti), assicurati di conoscere la codifica e di convertirla in UTF-8 il prima possibile e di tornare all'altra codifica il più tardi possibile.
Perché UTF-8? Poiché può rappresentare tutti i caratteri Unicode e quindi sostituisce tutte le codifiche esistenti a 7 e 8 bit e poiché è binario compatibile con ASCII, ovvero ogni stringa ASCII valida è anche una stringa UTF-8 valida (ma non vv .).
Nel tuo esempio, ciò che accade è questo.
Innanzitutto, si salva il file di origine; il tuo editor di testo è probabilmente configurato per utilizzare UTF-8, quindi la stringa letterale finisce con UTF-8 codificata su disco. PHP legge questo file, interpretando la stringa come una serie di byte; $original
ora contiene una stringa codificata UTF-8 di 7 caratteri, che è solo una sequenza di byte (sebbene contenga più di 7 byte, poiché ogni carattere è rappresentato da due o più byte). Se si chiama quindi echo $original
, la stringa codificata viene inviata al client così com'è; se hai detto al client di aspettarsi UTF-8, tutto va bene, ma se non lo hai fatto, PHP non ha modo di dire la differenza e finirai con la spazzatura nel browser. Come esperimento, prova questo:
$original = "शक्नोम्यत्तुम्";
echo strlen($original);
strlen
è codifica-agnostica e presuppone una codifica a 8 bit a larghezza fissa, ovvero un byte per carattere, quindi conterà i byte, non i caratteri.