首先,您需要了解带有 ó 或 î 之类的变音符号(来自您的示例)的字符不会自动成为“utf-8 字符”。它只是一个在不同字符集中具有不同编码(如果有)的字符,即使在那些具有共同基本单字节 ASCII 部分的字符集中(即英文字母、数字、最常见的标点符号和还有几个)。您可以将其称为“有问题的字符”,但不能称为“utf-8 字符”。
所以,当你写你的 footer 时<div>
,你并没有把它写成 UTF-8 编码。您的编辑器将这些字符保存在单字节编码中,例如ISO 8859-1或其亲属之一。
如果未指定,浏览器通常会自动检测页面中使用的编码。这就是为什么您最初能够在浏览器中准确地看到您在编辑器中编写的内容。
然后您尝试使用用户名中的“有问题的字符”登录。浏览器将您的页面解释为具有单字节编码,因此这导致它以相同的方式对您的表单输入进行编码,并将其以单字节编码发送回服务器。显然,编写 PHP 代码时没有考虑到这种可能性,因为它没有正确设置 的第三个参数htmlspecialchars()
,这是"UTF-8"
默认情况下的(从 PHP 5.4.0 开始 -"ISO-8859-1"
之前是这样)。由于带有“有问题的字符”的单字节编码字符串几乎从来都不是有效的 UTF-8 字符串(请参阅我对您的问题的评论,这是第二条评论),htmlspecialchars() 拒绝了它。
然后您正确添加了header('Content-Type: text/html; charset=utf-8');
,它禁用了浏览器的自动字符集检测。在这一点上,很明显您的带有页脚的文件<div>
不是 UTF-8 编码的(再次查看我的评论以解释出现的问号而不是“有问题的字符”)。
因此,您剩下要做的就是说服您的编辑器保存 UTF-8 编码的文件。正如其他人所指出的,以不同的编码保存文件并不适用于所有编辑器。从新文件开始有时是解决方案,可能是在将编辑器的默认编码设置为 UTF-8 之后。
要检查编码,您可以file
在 shell 中使用该命令。它的输出应该类似于
main.php: PHP script, UTF-8 Unicode text
或者,您可以使用该od -tx1z
命令将您的文件(可能| less
)转储为十六进制字节序列,旁边带有相应的字符串。如果文件是单字节编码的,那么您的“有问题的字符”将是单字节 >= 0x80。如果是 UTF-8 编码,它们将是 2 个字节的序列(其他将是 3 个或更多字节),全部 >= 0x80,而“非问题字符”将继续是单个字节 <0x80。
您提到的文章似乎写得很好,请按照它。
但是,如果您的所有页面都是使用 HTTP 标头生成的,则不需要文件AddDefaultCharset
中的指令,因为 Apache 指令的效果完全相同(并且最好在 PHP 中保持对编码的控制)。.htaccess
Content-Type: text/html; charset=utf-8
对于浏览器,添加<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
与上面的 HTTP 标头具有相同的效果(注意 http- equiv)。HTTP 标头更清晰,但是这个额外的元标记可能有助于在没有标头信息的情况下保存页面。
最重要的是,不要害怕UTF-8,因为它是你的朋友!
(......但是,从得到你赏金的答案中,我看到你和许多人一样,继续认为理解字符编码对你来说太难了☹)