Як встановити 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.