如何使用W3C验证程序中有效的PHP将HTTP标头设置为UTF-8?


319

我有几个PHP页面使用以下代码将各种内容回显到HTML页面中。

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

但是,当我使用W3C验证器进行验证时,它附带了:

HTTP标头(iso-8859-1)中指定的字符编码与元素(utf-8)中的值不同。

我对PHP还是很陌生,我想知道是否可以并且应该更改PHP文件的标头以匹配HTML文件。

Answers:


897

使用header修改HTTP标头:

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

请注意在将任何输出发送到客户端之前调用此函数。否则,标头也已发送,您显然无法再进行更改。您可以使用进行检查headers_sent。有关更多信息,请参见的手册页header


4
我只想补充一点,当您像这样正确设置HTTP标头时,您根本不需要<meta>标记。
乔恩

3
@乔恩:我会同时使用。META当未通过HTTP加载HTML文档(例如从磁盘)时,使用等效于HTTP的协议。
Gumbo 2010年

6
仅当正在执行的php(对于静态页面要执行此操作)时,您才应将HTML文件保存为utf-8。这样做会将已编码的BOM表字符utf-8添加到文件的开头。字节0xEF,0xBB,0xBF添加到文件的开头。大多数Web服务器都会注意到这一点并应用适当的标头。实际上,将您的php文件另存为utf-8,将完成相同的操作。
拉赫利2010年

1
@Jeremy Walton:不一定会添加UTF-8 BOM。实际上,对于UTF-8甚至没有必要,因为它只有一个字节顺序(但是可以用来标识UTF-8)。
浓汤

1
@Gumbo:当然,我在这里简化并针对迄今为止最常见的Web场景(问题似乎在讨论这种场景)。考虑到问题的明显程度,为什么当您甚至不了解某天它可能提供的优势时,为什么要做些什么?
乔恩


15

这是Web服务器发出与您定义的HTTP标头不匹配的HTTP标头的问题。有关如何使服务器发送正确的标头的说明,请参阅本页

否则,您也可以使用PHP修改标头,但这必须使用以下代码输出任何文本之前完成:

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

有关如何使用PHP发送头的更多信息,请参见头函数的文档


12

您还可以使用更短的方法:

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

参见RFC 2616。仅指定字符集是有效的。


我喜欢这个选项,因为(我假设)它将允许您分别设置内容类型的另一部分(例如,您有一些文本/纯文本页面和一些文本/ html页面,但它们都是UTF8。)我的理解正确吗?
埃里克·海斯特兰德

1
我找不到RFC 2616中说指定这种方式有效的部分。Content-Type = "Content-Type" ":" media-typemedia-type = type "/" subtype *( ";" parameter )
AI0867 '16

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 2014年

最后是设置字符编码的所有位置的完整列表。
Filip Overtone歌手Rydlo,2015年

mysql_query(“ SET NAMES utf8”); 在我的选择查询为我解决问题之前。谢谢:)
Deepak Goswami

7

如果设置为使用内部编码,则PHP自动发送标头:

ini_set('default_charset', 'utf-8');
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.