Come impostare l'intestazione HTTP su UTF-8 usando PHP che è valido nel validatore W3C?


319

Ho diverse pagine PHP che riecheggiano varie cose in pagine HTML con il seguente codice.

<meta http-equiv="Content-type" content="text/html; charset=utf-8" />

Tuttavia, quando convalido usando il validatore W3C viene fuori:

La codifica dei caratteri specificata nell'intestazione HTTP (iso-8859-1) è diversa dal valore nell'elemento (utf-8).

Sono abbastanza nuovo in PHP e mi chiedevo se potevo e dovevo cambiare l'intestazione per i file PHP in modo che corrispondessero ai file HTML.

Risposte:


897

Utilizzare headerper modificare l'intestazione HTTP:

header('Content-Type: text/html; charset=utf-8');

Nota di chiamare questa funzione prima che qualsiasi output sia stato inviato al client. In caso contrario, anche l'intestazione è stata inviata e ovviamente non è più possibile modificarla. Puoi verificarlo con headers_sent. Vedere la pagina di manuale diheader per ulteriori informazioni.


4
Vorrei solo aggiungere che quando si imposta correttamente l'intestazione HTTP in questo modo, non è più necessario il <meta>tag.
Jon,

3
@Jon: vorrei usare entrambi. L'equivalente HTTP METAviene utilizzato quando il documento HTML non viene caricato tramite HTTP (ad es. Dal disco).
Gumbo,

6
Funzionerà solo se esegui php, per farlo per le pagine statiche, dovresti salvare il tuo file html AS utf-8. In questo modo si aggiungerà il carattere BOM utf-8 codificato all'inizio del file. byte 0xEF, 0xBB, 0xBF aggiunti all'inizio del file. La maggior parte dei server Web noterà questo e applicherà l'intestazione appropriata. In effetti, il salvataggio del file php come utf-8 compirebbe la stessa cosa.
Rahly,

1
@Jeremy Walton: l'aggiunta della DBA UTF-8 non accade necessariamente. In realtà, non è nemmeno necessario per UTF-8 in quanto ha un solo ordine di byte (ma potrebbe essere utilizzato per identificare UTF-8).
Gumbo,

1
@Gumbo: certo, sto semplificando qui e prendendo di mira lo scenario web di gran lunga più comune (la domanda sembra parlare di questo scenario). Tenendo conto del livello apparente della domanda, perché fare qualcosa quando non capisci nemmeno quali sono i vantaggi che un giorno potrebbe offrire?
Jon,


15

Questo è un problema con il tuo server web che invia un'intestazione HTTP che non corrisponde a quella che hai definito. Per istruzioni su come fare in modo che il server invii le intestazioni corrette, consultare questa pagina .

Altrimenti, puoi anche usare PHP per modificare le intestazioni, ma questo deve essere fatto prima di inviare qualsiasi testo usando questo codice:

header('Content-Type: text/html; charset=utf-8');

Ulteriori informazioni su come inviare le intestazioni tramite PHP sono disponibili nella documentazione per la funzione di intestazione .


12

Puoi anche usare un modo più breve:

<?php header('Content-Type: charset=utf-8'); ?>

Vedi RFC 2616 . È valido per specificare solo set di caratteri.


Mi piace questa opzione, perché (presumo) ti consentirebbe di impostare separatamente l'altra parte del tipo di contenuto (ad esempio, hai alcune pagine di testo / semplici e alcune pagine di testo / html, ma sono tutte UTF8.) La mia comprensione è corretta?
Eric Seastrand,

1
Non riesco a trovare la parte di RFC 2616 che dice che è valido per specificare in quel modo. Content-Type = "Content-Type" ":" media-typeemedia-type = type "/" subtype *( ";" parameter )
AI0867,

1
Non è valido specificare solo il set di caratteri. Non è valido per RFC 2616 (che è comunque obsoleto) né per RFC 7231 (che non è obsoleto) né per qualsiasi altro RFC. Vedi stackoverflow.com/questions/41994062/…
sideshowbarker

10

Per un'implementazione corretta, è necessario modificare una serie di cose.

Database (immediatamente dopo la connessione):

mysql_query("SET NAMES utf8");

// Meta tag HTML (probably it's already set): 
meta charset="utf-8"
header php (before any output of the HTML):
header('Content-Type: text/html; charset=utf-8')
table-rows-charset (for each row):
utf8_unicode_ci

4
La coalizione del database non influenza l'output generato da PHP perché i dati sono codificati nel formato nativo configurato per l'uso con PHP prima che vengano mai restituiti all'utente. In secondo luogo, OP non ha menzionato che sta usando MySQL. In terzo luogo MyISAM è obsoleto e non dovrebbe essere raccomandato a meno che non si sappia cosa si sta facendo. C'è una ragione per cui InnoDB è diventato il nuovo predefinito.
EWit

infine un elenco completo di tutti i luoghi in cui impostare la codifica dei caratteri.
Filip OvertoneSinger Rydlo,

mysql_query ("SET NAMES utf8"); prima che la mia query selezionata risolvesse il problema per me. grazie :)
Deepak Goswami il

7

PHP invia automaticamente le intestazioni se impostato per utilizzare la codifica interna:

ini_set('default_charset', 'utf-8');
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.