Prima di tutto, è necessario capire che un personaggio con un segno diacritico come ó o î (dal tuo esempio) non è automaticamente un "carattere utf-8". È semplicemente un personaggio che ha diverse codifiche (se ce ne sono) in set di caratteri diversi, anche in quei set di caratteri che hanno in comune la parte ASCII single-byte di base (cioè l'alfabeto inglese, le cifre, la punteggiatura più comune, e un po 'di più). Potresti chiamarlo un "personaggio problematico", ma non un "carattere utf-8".
Quindi, quando hai scritto il footer <div>
, NON lo hai scritto codificato in UTF-8. Il tuo editor ha salvato quei caratteri in una codifica a byte singolo, come ISO 8859-1 o uno dei suoi parenti.
I browser normalmente rilevano automaticamente la codifica utilizzata in una pagina, se non è specificata. Questo è il motivo per cui inizialmente eri in grado di vedere nel browser esattamente ciò che avevi scritto nel tuo editor.
Quindi si è tentato di accedere con un "carattere problematico" nel nome utente. Il browser ha interpretato la tua pagina come una codifica a byte singolo, quindi questo ha causato la codifica dell'input del modulo nello stesso modo e l'invio di codifica a byte singolo al server. Il codice PHP non è stato scritto pensando a questa possibilità, apparentemente, perché non ha impostato correttamente il terzo parametro di htmlspecialchars()
, che è "UTF-8"
per impostazione predefinita (a partire da PHP 5.4.0 - era "ISO-8859-1"
prima). Poiché una stringa codificata a byte singolo con "caratteri problematici" non è quasi mai una stringa UTF-8 valida (vedere il mio commento alla domanda, è il secondo commento), htmlspecialchars() lo ha respinto.
Quindi è stato aggiunto correttamente lo header('Content-Type: text/html; charset=utf-8');
, che ha disabilitato il rilevamento del set di caratteri automatico dal browser. A questo punto è diventato evidente che il tuo file con il footer <div>
non era codificato in UTF-8 (vedi di nuovo il mio commento per la spiegazione dei punti interrogativi che appaiono al posto dei "caratteri problematici").
Quindi tutto ciò che resta da fare è convincere il tuo editore a salvare i file codificati in UTF-8. Come altri hanno notato, il salvataggio del file in una codifica diversa non funziona in tutti gli editor. A partire da un nuovo file a volte è la soluzione, forse dopo aver impostato la codifica predefinita del tuo editor su UTF-8.
Per verificare la codifica, è possibile utilizzare il comando file
in una shell. La sua uscita dovrebbe essere qualcosa di simile
main.php: PHP script, UTF-8 Unicode text
Oppure, è possibile utilizzare il comando od -tx1z
, che scarica il file (forse | less
), come una sequenza di byte esadecimali con la stringa corrispondente sul lato. Se il file è codificato a byte singolo, i "caratteri problematici" saranno byte singoli> = 0x80. Se è codificato in UTF-8, saranno sequenze di 2 byte (altri saranno 3 o più byte), tutti> = 0x80, mentre i "caratteri non problematici" continueranno a essere singoli byte < 0x80.
L'articolo che citi sembra essere ben scritto, basta seguirlo.
non ti servono la direttiva AddDefaultCharset
nel file .htaccess
, però, se tutte le pagine sono generate con l'intestazione Content-Type: text/html; charset=utf-8
HTTP, perché l'effetto della direttiva Apache è esattamente lo stesso (ed è bene tenere il controllo sulla codifica all'interno di PHP).
L'aggiunta dello <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
ha lo stesso effetto, per il browser, dell'intestazione HTTP di cui sopra (si noti l'http equiv). L'intestazione HTTP è più pulita, ma questo meta tag aggiuntivo può essere d'aiuto nel caso in cui una pagina venga salvata senza le informazioni dell'intestazione.
Soprattutto, non aver paura di UTF-8, perché è tuo amico!
(... ma, dalla risposta che ha ottenuto la vostra generosità, vedo che tu, come molte persone, continua a pensare che la comprensione codifiche dei caratteri è troppo difficile per voi ☹)
Sto avendo lo stesso problema. Hai mai trovato una soluzione? – coderama
quei punti interrogativi sono il risultato di sequenze di byte UTF-8 non valide. Molto probabilmente stai usando un editor che ha salvato il testo in una codifica a byte singolo, ad esempio, [ISO 8859-1] (http://en.wikipedia.org/wiki/ISO/IEC_8859-1). In tutte le codifiche a byte singolo che sono estensioni di ASCII, la parte estesa ha valori di byte> = 128. Tutti i caratteri a byte singolo di UTF-8 sono <128, tutti i caratteri multibyte sono byte> = 128. Questo è il motivo I caratteri ISO 8859-x con segni diacritici diventano punti interrogativi: non potrebbero mai essere UTF-8 validi, salvo in combinazioni abbastanza improbabili. –