$_COOKIE 全局变量编码

$_COOKIE global var encoding

我知道,我不应该使用 ISO-8859-1,但是我有这个网站是为我处理的,不可能将所有 PHP/JS/HTML 迁移到使用 UTF-8 而不是 ISO-8859 -1.

我的问题是:此网站使用 encodeURIComponent 将值存储在 Javascript 的 cookie 中。例如,在 index.html 文件(使用 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />)中有一个 <script> 标签,其中包含以下代码:

document.cookie = "xxx=" + encodeURIComponent("não") + ";.....";

cookie 值存储为 n%C3%A3o(我在“应用程序”选项卡中检查了 Chrome 上的开发工具)。尽管 HTML 文件是 ISO,但 cookie 保存为 UTF-8。伟大的!这正是 encodeURIComponent 的工作原理,它总是会将其转换为 UTF-8。

当 PHP 页面使用这个 xxx cookie 值做一些事情时,问题就来了。由于所有 PHP 文件都保存为 ISO-8859-1,当它尝试访问 $_COOKIE["xxx"] 时,问题开始发生,例如字符被损坏。

显然我必须使用 utf8_decode($_COOKIE["xxx"]) 来解决这个问题,因为它获取 cookie 值并将其解析为 ISO-8859-1。

问题是该网站有数百个 PHP 文件,这些文件在各处都使用 cookie。更改所有代码行将需要大量时间 - 我没有时间,因为我的老板希望今天解决这个问题。

所以我的问题来了:

1) PHP 如何知道应该将 cookie 读取为 UTF-8 并将 UTF-8 编码分配给 $_COOKIE ?当我访问 $_COOKIE 时,它显然已经解码了 cookie 值,因为 %xx 已经被解码了。我知道你可以说 Of course you dumb, cookies are all the time stored as UTF-8.。但这并不总是正确的。

如果在 PHP 文件(使用 ISO-8859-1 编码保存)中,我这样做:

setcookie("xxx","não");

当我检查 cookie 时(在 Chrome 开发工具 -> 应用程序选项卡中)它显示 n%E3o

看到了吗? n%E3o 不同于 n%C3%A3o

那么,在解析 cookie 时,PHP 是如何知道 n%E3o 应该被解码为 ISO-8859-1 而 PHP 是如何知道 n%C3%A3o应该解码为UTF-8?

我知道_GET_POST_COOKIE超级全局变量被PHP自动解码。但它如何知道源字符集以及如何决定输出哪个字符集?

PHP 根本 "know" 根本不关心编码。在这种情况下,它不需要。 Percent-encoding,用于 cookie 的内容,明确地在编码中性字节级别工作。意思是,编码本身表示原始字节。 %C3%A3表示两个字节0xC3A3,是字符“ã”的UTF-8编码。或者如果您将它们读作 ISO-8859-1,则它是字符“ã”的编码。所以 PHP 只是将百分比编码解码为原始字节;最终成为什么样的角色取决于你用什么来解释它们。 PHP 根本不解释它们,PHP 字符串只是原始字节数组。

相反,PHP 源代码文件中的任何字符串文字同样只是一个原始字节数组,其内容取决于保存源代码文件的编码。在 PHP 文件中保存为 ISO-8859-1,字符串文字 "não" 包含字节 0x6EF16F。存储为 UTF-8 的同一文件包含字节 0x6EC3A36F。在百分比编码中,这些原始字节只是按原样编码。

有关该主题的更多详细信息,请参阅 What Every Programmer Absolutely, Positively Needs To Know About Encodings And Character Sets To Work With Text