ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

但是,当我使用 W3C validator 进行验证时,它会出现:

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

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


G
Gumbo

使用 header 修改 HTTP 标头:

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

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


我只想补充一点,当您像这样正确设置 HTTP 标头时,您就不再需要 <meta> 标记了。
@Jon:我会同时使用两者。当 HTML 文档不是通过 HTTP 加载(例如从磁盘)时,使用与 HTTP 等效的 META
这仅在您执行 php 时才有效,要为静态页面执行此操作,您应该将 html 文件保存为 utf-8。这样做会将 BOM 字符 utf-8 编码添加到文件的开头。字节 0xEF、0xBB、0xBF 添加到文件的开头。大多数 Web 服务器会注意到这一点并应用适当的标头。事实上,将您的 php 文件保存为 utf-8,可以完成同样的事情。
@Jeremy Walton:不一定会添加 UTF-8 BOM。事实上,UTF-8 甚至没有必要,因为它只有一个字节顺序(但它可以用来识别 UTF-8)。
@Gumbo:当然,我在这里简化并针对迄今为止最常见的网络场景(问题似乎在谈论这种场景)。考虑到问题的明显程度,当您甚至不了解某天可能提供的优势是什么时,为什么要做某事?
P
Peter Mortensen

首先确保 PHP 文件本身经过 UTF-8 编码。

某些浏览器会忽略元标记。如果您只使用 ASCII 字符,那也没关系。

http://en.wikipedia.org/wiki/List_of_HTTP_header_fields

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

P
Peter Mortensen

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

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

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

有关如何使用 PHP 发送标头的更多信息,请参见 the documentation for the header function


P
Peter Mortensen

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

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

请参阅RFC 2616。只指定字符集是有效的。


我喜欢这个选项,因为(我假设)它允许您单独设置内容类型的另一部分(例如,您有一些 text/plain 页面和一些 text/html 页面,但它们都是 UTF8。)我的理解正确吗?
我找不到 RFC 2616 中说明以这种方式指定是有效的部分。 Content-Type = "Content-Type" ":" media-typemedia-type = type "/" subtype *( ";" parameter )
只指定字符集是无效的。根据 RFC 2616(无论如何都已过时)、RFC 7231(尚未过时)或任何其他 RFC,它均无效。请参阅stackoverflow.com/questions/41994062/…
你确定你没有把它和 HTML5 的 meta charset 属性混淆吗?
P
Peter Mortensen

为了正确实现,您需要更改一系列内容。

数据库(连接后立即):

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

数据库的联盟不会影响 PHP 生成的输出,因为数据在返回给用户之前被编码为配置为与 PHP 一起使用的本机格式。其次,OP 没有提到他正在使用 MySQL。第三,MyISAM 已过时,除非您知道自己在做什么,否则不应推荐使用 InnoDB 成为新的默认设置是有原因的。
最后是设置字符编码的所有地方的完整列表。
mysql_query("设置名称 utf8");在我的选择查询为我解决问题之前。谢谢 :)
P
Peter Mortensen

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

ini_set('default_charset', 'utf-8');

R
Rodolfo Bojo Pellegrino

http://php.net/default-charset 所述,

“UTF-8”是默认值,如果省略 encoding 参数,则其值用作 htmlentities()、html_entity_decode() 和 htmlspecialchars() 的默认字符编码。

它在“数据处理”部分的默认 php.ini 中设置为“UTF-8”:

; PHP's default character set is set to UTF-8.
; http://php.net/default-charset
default_charset = "UTF-8"

此外,您可以根据需要在内容之前将 header 设置为另一种编码:

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

或者

header('Content-Type: text/html; charset=iso-8859-1');

或您需要声明的任何其他字符集。