[英]Understanding character encoding in PHP
我正在努力理解PHP中的字符编码。
考虑以下脚本(您可以在此处运行):
$string = "\xe2\x82\xac";
var_dump(mb_internal_encoding());
var_dump($string);
var_dump(unpack('C*', $string));
$utf8string = mb_convert_encoding($string, "UTF-8");
var_dump($utf8string);
var_dump(unpack('C*', $utf8string));
mb_internal_encoding("UTF-8");
var_dump($string);
var_dump($utf8string);
我有一个字符串,实际上是€字符,用unicode代码点表示。 高达PHP 5.5
,使用的内部编码是ISO-8859-1
,因此我认为我的字符串将使用此编码进行编码。 使用unpack
我可以看到我的字符串的咬合表示,它对应于我用来定义字符串的十六进制代码。
然后我使用mb_convert_encoding
将字符串的编码转换为UTF-8
。 此时,字符串在屏幕上的显示方式不同,其字节表示也会发生变化(这是预期的)。
如果我将PHP
内部编码也改为UTF-8
,我希望在屏幕上正确显示utf8string
,但这不会发生。
我错过了什么?
您显示的脚本不使用任何非ascii字符,因此其内部编码没有任何区别。 mb_internal_encoding
确实会在输出中转换您的数据。 这个问题会告诉你更多它是如何工作的; 它也会告诉你最好不要使用它。
代码中的三字节字符串$string
是欧元符号的UTF-8表示形式,而不是其“unicode代码点”(宽度为2字节,与所有常见的Unicode字符一样: 0x20ac
)。
这会清除你看到的行为吗?
您从一个字符串开始,该字符串是欧元符号的utf-8
表示。 如果你运行echo($string)
所有版本的PHP都会产生你放在$string
的三个字节。 浏览器如何解释它们取决于Content-Type
标头中指定的字符集。 如果是text/html; charset=utf-8
text/html; charset=utf-8
然后你在渲染页面中得到欧元符号。
然后你做错了。 你只用两个参数调用mb_convert_encoding()
。 这允许PHP使用mb_string
扩展使用的内部编码的当前值作为第三个参数( $from_encoding
)。 为什么?
对于PHP 5.6及更高版本, mb_internal_encoding()
返回的默认值为utf-8
,对mb_convert_encoding()
的调用为no-op。
但是对于以前版本的PHP, mb_internal_encoding()
返回的默认值是iso-8859-1
,它与字符串的编码不匹配。 因此, mb_convert_encoding()
将$string
的字节解释为三个单独的字符,并使用utf-8
的规则对它们进行编码。 结果显然是错误的。
顺便说一下,如果用'€'
初始化$string
,你会在所有PHP版本上获得相同的输出(即使在PHP 4,iirc上)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.