Comment définir l'en-tête HTTP sur UTF-8 en utilisant PHP qui est valide dans le validateur W3C?


319

J'ai plusieurs pages PHP faisant écho à diverses choses dans des pages HTML avec le code suivant.

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

Cependant, lorsque je valide en utilisant le validateur W3C, il arrive:

Le codage de caractères spécifié dans l'en-tête HTTP (iso-8859-1) est différent de la valeur de l'élément (utf-8).

Je suis assez nouveau sur PHP, et je me demandais si je pouvais et devrais changer l'en-tête des fichiers PHP pour qu'ils correspondent aux fichiers HTML.

Réponses:


897

Utilisez headerpour modifier l'en-tête HTTP:

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

Notez d'appeler cette fonction avant d'envoyer une sortie au client. Sinon, l'en-tête a également été envoyé et vous ne pouvez évidemment plus le modifier. Vous pouvez vérifier cela avec headers_sent. Voir la page de manuel deheader pour plus d'informations.


4
J'ajouterais seulement que lorsque vous définissez correctement l'en-tête HTTP comme ceci, vous n'avez plus besoin de la <meta>balise.
Jon

3
@ Jon: J'utiliserais les deux. L'équivalent HTTP METAest utilisé lorsque le document HTML n'est pas chargé via HTTP (par exemple à partir du disque).
Gumbo

6
Cela ne fonctionnera que si votre php en cours d'exécution, pour le faire pour les pages statiques, vous devez enregistrer votre fichier html AS utf-8. Cela ajoutera le caractère de nomenclature utf-8 encodé au début du fichier. octets 0xEF, 0xBB, 0xBF ajoutés au début du fichier. La plupart des serveurs Web le remarqueront et appliqueront l'en-tête approprié. En fait, enregistrer votre fichier php sous le nom utf-8 accomplirait la même chose.
Rahly

1
@Jeremy Walton: Que la nomenclature UTF-8 soit ajoutée ne se produit pas nécessairement. En fait, ce n'est même pas nécessaire pour UTF-8 car il n'a qu'un ordre d'octets (mais il pourrait être utilisé pour identifier UTF-8).
Gumbo

1
@Gumbo: bien sûr, je simplifie ici et cible le scénario web de loin le plus courant (la question semble parler de ce scénario). Compte tenu du niveau apparent de la question, pourquoi faire quelque chose alors que vous ne comprenez même pas quels sont les avantages qu'elle peut un jour offrir?
Jon


15

Il s'agit d'un problème avec l'envoi par votre serveur Web d'un en-tête HTTP qui ne correspond pas à celui que vous définissez. Pour obtenir des instructions sur la manière d'envoyer au serveur les en-têtes appropriés, consultez cette page .

Sinon, vous pouvez également utiliser PHP pour modifier les en-têtes, mais cela doit être fait avant de sortir du texte en utilisant ce code:

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

Plus d'informations sur la façon d'envoyer des en-têtes en utilisant PHP peuvent être trouvées dans la documentation de la fonction d'en-tête .


12

Vous pouvez également utiliser une méthode plus courte:

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

Voir RFC 2616 . Il est valide de spécifier uniquement le jeu de caractères.


J'aime cette option, car (je suppose) elle vous permettrait de définir l'autre partie du type de contenu séparément (par exemple, vous avez du texte / des pages simples et des pages de texte / html, mais elles sont toutes UTF8.) Ma compréhension est-elle correcte?
Eric Seastrand

1
Je ne trouve pas la partie de la RFC 2616 qui dit qu'il est valide de spécifier de cette façon. Content-Type = "Content-Type" ":" media-typeetmedia-type = type "/" subtype *( ";" parameter )
AI0867

1
Il n'est pas valide de spécifier uniquement le jeu de caractères. Ce n'est pas valide par RFC 2616 (qui est de toute façon obsolète) ni par RFC 7231 (qui n'est pas obsolète) ni par aucun autre RFC. Voir stackoverflow.com/questions/41994062/…
sideshowbarker

10

Pour une implémentation correcte, vous devez modifier une série de choses.

Base de données (immédiatement après la connexion):

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 coalition de la base de données n'influence pas la sortie générée par PHP car les données sont encodées au format natif configuré pour être utilisé avec PHP avant d'être retournées à l'utilisateur. Deuxièmement, OP n'a pas mentionné qu'il utilise MySQL. Troisièmement, MyISAM est obsolète et ne devrait pas être recommandé à moins que vous ne sachiez ce que vous faites. Il y a une raison pour laquelle InnoDB est devenu le nouveau défaut.
EWit

enfin une liste complète de tous les endroits où définir l'encodage des caractères.
Filip OvertoneSinger Rydlo

mysql_query ("SET NAMES utf8"); avant que ma requête de sélection ne corrige le problème pour moi. merci :)
Deepak Goswami

7

PHP envoie automatiquement les en-têtes s'il est configuré pour utiliser l'encodage interne:

ini_set('default_charset', 'utf-8');
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.