Як встановити HTTP-заголовок на UTF-8 за допомогою PHP, який дійсний у валідаторі W3C?


319

У мене є кілька сторінок PHP, які повторюють різні речі на HTML- сторінки із наступним кодом.

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

Однак, коли я перевіряю за допомогою валідатора W3C, він створює:

Кодування символів, вказане в заголовку HTTP (iso-8859-1), відрізняється від значення в елементі (utf-8).

Я зовсім новачок у PHP, і мені було цікаво, чи можу я та мушу змінити заголовок для PHP-файлів на HTML-файли.

Відповіді:


897

Використовуйте headerдля зміни заголовка HTTP:

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

Примітка для виклику цієї функції до того, як будь-який вихід буде надісланий клієнтові. Інакше заголовок також надісланий, і ви, очевидно, більше не можете його змінити. Ви можете перевірити це за допомогою headers_sent. Додаткову інформацію див . На сторінці керівництваheader .


4
Я хотів би лише додати, що коли ви правильно встановили заголовк HTTP так, <meta>тег вам більше не потрібен .
Jon

3
@Jon: Я б використовував і те, і інше. HTTP-еквівалент METAвикористовується, коли HTML-документ не завантажується через HTTP (наприклад, з диска).
Gumbo

6
Це буде працювати лише в тому випадку, якщо ваш виконавець php, щоб зробити це для статичних сторінок, вам слід зберегти свій html-файл AS utf-8. Це додасть символу BOM utf-8, закодованого до початку файлу. байти 0xEF, 0xBB, 0xBF додані до початку файлу. Більшість веб-серверів помітять це і застосують відповідне заголовка. Насправді збереження вашого php-файлу як utf-8 дозволило б виконати те саме.
Рахлі

1
@ Джеремі Уолтон: Додавання BOM UTF-8 відбувається не обов'язково. Насправді, це навіть не потрібно для UTF-8, оскільки він має лише один порядок байт (але він може бути використаний для ідентифікації UTF-8).
Gumbo

1
@Gumbo: звичайно, я спрощую тут і орієнтуюся на найбільш поширений веб-сценарій (питання, схоже, говорить про цей сценарій). Беручи до уваги очевидний рівень питання, навіщо робити щось, коли ви навіть не розумієте, які переваги він може колись надати?
Jon


15

Це проблема із тим, що ваш веб-сервер надсилає заголовок HTTP, який не відповідає вказаному вами. Інструкції щодо того, як змусити сервер надсилати правильні заголовки, дивіться на цій сторінці .

В іншому випадку ви також можете використовувати PHP для зміни заголовків, але це потрібно зробити перед виведенням будь-якого тексту за допомогою цього коду:

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

Більше інформації про те, як надсилати заголовки за допомогою PHP, можна знайти в документації до функції заголовка .


12

Ви також можете скористатися більш коротким способом:

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

Див. RFC 2616 . Дійсно вказати лише набір символів.


Мені подобається цей варіант, тому що (я припускаю) він дозволив би встановити іншу частину типу вмісту окремо (наприклад, у вас є кілька текстових / звичайних сторінок та деякі сторінки тексту / html, але всі вони є UTF8.) Чи правильно я розумію?
Ерік Seastrand

1
Я не можу знайти частину RFC 2616, яка каже, що правильно вказати цей спосіб. Content-Type = "Content-Type" ":" media-typeтаmedia-type = type "/" subtype *( ";" parameter )
AI0867

1
Неправильно вказувати лише шаблони. Це не дійсно ні за RFC 2616 (який так чи інакше є застарілим), ні за RFC 7231 (який не є застарілим), ні для будь-якого іншого RFC. Дивіться stackoverflow.com/questions/41994062/…
sideshowbarker

10

Для правильної реалізації потрібно змінити ряд речей.

База даних (відразу після з'єднання):

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
Коаліція бази даних не впливає на вихід, генерований PHP, оскільки дані кодуються у вихідному форматі, налаштованому для використання з PHP до того, як він коли-небудь повернеться користувачеві. По-друге, OP не згадував, що він використовує MySQL. По-третє, MyISAM є застарілим, і його не рекомендують рекомендувати, якщо ви не знаєте, що ви робите. Існує причина, що InnoDB став новим за замовчуванням.
EWit

нарешті повний список усіх місць для встановлення кодування символів.
Filip OvertoneSinger Rydlo

mysql_query ("Встановити імена utf8"); перш ніж мій запит вибору вирішив проблему. дякую :)
Deepak Goswami

7

PHP автоматично надсилає заголовки, якщо вони встановлені для використання внутрішнього кодування:

ini_set('default_charset', 'utf-8');
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.