Wie setze ich den HTTP-Header mit PHP auf UTF-8, das im W3C-Validator gültig ist?


319

Ich habe mehrere PHP- Seiten, die verschiedene Dinge in HTML- Seiten mit dem folgenden Code wiedergeben.

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

Wenn ich jedoch mit dem W3C-Validator validiere, wird Folgendes angezeigt :

Die im HTTP-Header (iso-8859-1) angegebene Zeichenkodierung unterscheidet sich vom Wert im Element (utf-8).

Ich bin ziemlich neu in PHP und habe mich gefragt, ob ich den Header für die PHP-Dateien so ändern könnte und sollte, dass er mit den HTML-Dateien übereinstimmt.

Antworten:


897

Verwenden Sie headerdiese Option, um den HTTP-Header zu ändern:

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

Beachten Sie, dass Sie diese Funktion aufrufen müssen, bevor eine Ausgabe an den Client gesendet wurde. Andernfalls wurde auch der Header gesendet und Sie können ihn offensichtlich nicht mehr ändern. Sie können das mit überprüfen headers_sent. Weitere Informationen finden Sie auf der Handbuchseite vonheader .


4
Ich würde nur hinzufügen, dass Sie das <meta>Tag überhaupt nicht mehr benötigen, wenn Sie den HTTP-Header so richtig einstellen .
Jon

3
@ Jon: Ich würde beide verwenden. Das HTTP-Äquivalent METAwird verwendet, wenn das HTML-Dokument nicht über HTTP (z. B. von der Festplatte) geladen wird.
Gumbo

6
Dies funktioniert nur, wenn Sie PHP ausführen. Um dies für statische Seiten zu tun, sollten Sie Ihre HTML-Datei als utf-8 speichern. Dadurch wird das Stücklistenzeichen utf-8 am Anfang der Datei hinzugefügt. Bytes 0xEF, 0xBB, 0xBF am Anfang der Datei hinzugefügt. Die meisten Webserver werden dies bemerken und den entsprechenden Header anwenden. In der Tat würde das Speichern Ihrer PHP-Datei als utf-8 das gleiche erreichen.
Rahly

1
@ Jeremy Walton: Dass die UTF-8-Stückliste hinzugefügt wird, muss nicht unbedingt geschehen. Tatsächlich ist es für UTF-8 nicht einmal erforderlich, da es nur eine Bytereihenfolge hat (aber es könnte verwendet werden, um UTF-8 zu identifizieren).
Gumbo

1
@Gumbo: Sicher, ich vereinfache hier und ziele auf das mit Abstand häufigste Web-Szenario ab (die Frage scheint über dieses Szenario zu sprechen). Unter Berücksichtigung des offensichtlichen Niveaus der Frage, warum etwas tun, wenn Sie nicht einmal verstehen, welche Vorteile es eines Tages bieten könnte?
Jon


15

Dies ist ein Problem, wenn Ihr Webserver einen HTTP-Header sendet, der nicht mit dem von Ihnen definierten übereinstimmt. Anweisungen dazu, wie der Server die richtigen Header sendet, finden Sie auf dieser Seite .

Andernfalls können Sie auch PHP verwenden, um die Header zu ändern. Dies muss jedoch erfolgen, bevor Sie Text mit diesem Code ausgeben:

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

Weitere Informationen zum Versenden von Headern mit PHP finden Sie in der Dokumentation zur Header-Funktion .


12

Sie können auch einen kürzeren Weg verwenden:

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

Siehe RFC 2616 . Es ist gültig, nur den Zeichensatz anzugeben.


Ich mag diese Option, weil (ich nehme an) Sie damit den anderen Teil des Inhaltstyps separat festlegen können (z. B. haben Sie einige Text- / Nur-Seiten- und einige Text- / HTML-Seiten, aber alle sind UTF8.) Ist mein Verständnis richtig?
Eric Seastrand

1
Ich kann den Teil von RFC 2616 nicht finden, der besagt, dass es gültig ist, diesen Weg anzugeben. Content-Type = "Content-Type" ":" media-typeundmedia-type = type "/" subtype *( ";" parameter )
AI0867

1
Es ist nicht gültig, nur den Zeichensatz anzugeben. Es ist weder nach RFC 2616 (der ohnehin veraltet ist) noch nach RFC 7231 (der ohnehin nicht veraltet ist) oder nach einem anderen RFC gültig. Siehe stackoverflow.com/questions/41994062/...
sideshowbarker

10

Für eine korrekte Implementierung müssen Sie eine Reihe von Dingen ändern.

Datenbank (unmittelbar nach der Verbindung):

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
Die Koalition der Datenbank hat keinen Einfluss auf die von PHP generierte Ausgabe, da die Daten in das native Format codiert werden, das für die Verwendung mit PHP konfiguriert ist, bevor sie jemals an den Benutzer zurückgegeben werden. Zweitens hat OP nicht erwähnt, dass er MySQL verwendet. Drittens ist MyISAM veraltet und sollte nur empfohlen werden, wenn Sie wissen, was Sie tun. Es gibt einen Grund, warum InnoDB zum neuen Standard wurde.
EWit

Schließlich eine vollständige Liste aller Stellen, an denen die Zeichenkodierung festgelegt werden soll.
Filip OvertoneSinger Rydlo

mysql_query ("SET NAMES utf8"); bevor meine Auswahlabfrage das Problem für mich behoben hat. danke :)
Deepak Goswami

7

PHP sendet Header automatisch, wenn die interne Codierung verwendet wird:

ini_set('default_charset', 'utf-8');
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.