Una stringa PHP è solo una sequenza di byte, senza alcuna codifica taggata ad esso. I valori di stringa possono provenire da varie fonti: il client (su HTTP), un database, un file o da stringhe letterali nel codice sorgente. PHP legge tutti questi come sequenze di byte e non estrae mai alcuna informazione di codifica.
Se tutte le origini e le destinazioni dei dati utilizzano la stessa codifica, la cosa peggiore che può accadere è che le posizioni delle stringhe sono sbagliate (se si usano codifiche multi-byte), poiché PHP conterrà byte, non caratteri.
Ma se le codifiche non corrispondono (ad esempio, scrivi una stringa letterale in un file sorgente memorizzato come UTF-8 e poi la mandi in un database che si aspetta Latin-1), PHP non eseguirà alcuna conversione per te : copierà felicemente i byte su raw.
La soluzione più sicura è questa:
- Imposta la codifica interna di PHP su UTF-8.
- Salva tutti i tuoi file sorgente come UTF-8.
- Utilizza UTF-8 come codifica di output (non dimenticare di inviare intestazioni
Content-type
idonee).
- Imposta 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 converti in UTF-8 il prima possibile e di tornare all'altra codifica il più tardi possibile.
Perché UTF-8? Perché può rappresentare tutti i caratteri Unicode e quindi sostituisce tutte le codifiche esistenti a 7 bit e 8 bit, e poiché è compatibile binario con ASCII, cioè ogni stringa ASCII valida è anche una stringa UTF-8 valida (ma non vv .).
Nel tuo esempio, ciò che accade è questo.
Per prima cosa, salvi il tuo file sorgente; il tuo editor di testo è probabilmente configurato per utilizzare UTF-8, quindi il tuo letterale stringa termina con codifica UTF-8 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é ciascun carattere è rappresentato da due o più byte). Se poi chiami echo $original
, la stringa codificata viene inviata al client così com'è; se hai detto al cliente di aspettarsi UTF-8, va tutto bene, ma se non lo hai, PHP non ha modo di dire la differenza, e finirai con la spazzatura nel browser. Come esperimento, prova questo:
$original = "शक्नोम्यत्तुम्";
echo strlen($original);
strlen
è codificatore-agnostico e presuppone una codifica a 8 bit a larghezza fissa, ovvero un byte per carattere, quindi conteggia i byte, non i caratteri.