1 回答
TA贡献1815条经验 获得超10个赞
您示例中的字节数组不是有效的 UTF-8。基本上,如果您在 C# 输出中看到 �� 符号,则表示Encoding.UTF8.GetString()
使用替换字符来表示无法转换为输出字符的编码输入字节序列。
但是,您仍然可以在 PHP 中重现完全相同的行为Encoding.UTF8.GetString()
:
$bytes32 = [144, 204, 205, 119, 77, 176, 172, 140, 110, 162, 222, 255, 14, 38, 252, 82, 118, 138, 130, 124, 145, 199, 55, 162, 224, 80, 102, 141, 140, 57, 194, 36];
$string32 = \pack('C*', ...$bytes32);
$string32Utf8 = \mb_convert_encoding($string32, 'ASCII', 'UTF-8');
$bytes70 = [239, 191, 189, 239, 191, 189, 239, 191, 189, 119, 77, 239, 191, 189, 239, 191, 189, 239, 191, 189, 110, 239, 191, 189, 239, 191, 189, 239, 191, 189, 14, 38, 239, 191, 189, 82, 118, 239, 191, 189, 239, 191, 189, 124, 239, 191, 189, 239, 191, 189, 55, 239, 191, 189, 239, 191, 189, 80, 102, 239, 191, 189, 239, 191, 189, 57, 239, 191, 189, 36];
$string70 = \pack('C*', ...$bytes70);
$string70Utf8 = \mb_convert_encoding($string70, 'ASCII', 'UTF-8');
\var_dump($string32Utf8, $string70Utf8, $string32Utf8 === $string70Utf8);
我做的不同的事情:
由于 byte array 表示UTF-8 string,我们不能使用
chr
将其转换为二进制字符串。如chr
函数文档中所述:此函数不知道任何字符串编码,特别是不能传递 Unicode 代码点值以生成多字节编码(如 UTF-8 或 UTF-16)的字符串。
pack
另一方面,函数可以处理各种类型的二进制数据格式。\pack('C*', ...$bytes32)
意味着字节数组将被视为一系列无符号字符并打包成二进制字符串。utf8_decode
函数有一个非常混乱的名字;它应该被命名为类似的东西,utf8_to_iso88591
因为这正是它的作用:将包含以 UTF-8 编码的 ISO-8859-1 字符的字符串转换为单字节 ISO-8859-1
如果我们想复制
Encoding.UTF8.GetString()
示例,我们真正需要做的是将 UTF-8 编码的二进制字符串转换为 ASCII。你可以使用mb_convert_encoding
函数来做到这一点,就像这样:mb_convert_encoding($utf8String, 'ASCII', 'UTF-8')
希望这些评论会有所帮助!
- 1 回答
- 0 关注
- 136 浏览
添加回答
举报