PHP mb_convert_encoding 从 UTF-8 转换为 SHIFT JIS 是错误的

PHP mb_convert_encoding convert from UTF-8 to SHIFT JIS is wrong

提问人:Ihenry 提问时间:7/15/2022 更新时间:7/17/2022 访问量:876

问:

我使用mb_convert_encoding函数将 UTF8 字符转换为 SJIS 字符。

转换前:でんぱ組 出会いの歌26 カミソヤマ ユニ

After conversion: て?んは?組 出会いの歌26 カミソヤマ ユニ

不可转换字符:て?んは?

用于转换的代码:

$str = mb_convert_encoding('でんぱ組 出会いの歌26 カミソヤマ ユニ', "SJIS", "UTF-8");
PHP 编码 UTF-8 Shift-JIS MB-Convert-Encoding

评论

0赞 arkascha 7/15/2022
因此,这些字符很可能没有有效的转换。这就是为什么它们必须被转录。

答:

0赞 AmigoJack 7/17/2022 #1

因为 1 字素只是组成 2 个 Unicode 代码点的渲染,并且(不要与无法组合的代码点混淆)——前者可以从 UTF-8 转换为 Shift-JIS,后者则不然。◌゙

与以下相同: - 它由一个字符组合而成,而不是一个字符:◌゚

◌゙ ◌゚
Unicode的 U+3066 U+3067 U+3099型 U+3071 U+306F型 U+309A型
UTF-8 格式 e3 81 a6 e3 81 a6 e3 82 99 e3 81 b1 e3 81 af e3 82 9a
Shift-JIS
或 CP932
82 c5 82 c4 (不存在) 82 cf 82 cd (不存在)

仅仅因为您在 Unicode 中看到 1 个字素(例如 で 或 ぱ)(例如 UTF-8),这并不意味着它是从 1 个代码点构建的。你既不能相信你的眼睛,也不能相信你的用户的输入——它要么真的是 1 个代码点,要么不是。在将 UTF-8 文本转换为 Shift-JIS 之前,您必须对 UTF-8 文本(例如 NFC 形式进行规范化,因为 1 个字素的 2 个代码点(U+3067 和 U+3099)也变成了 1 个代码点 (U+3066),然后也可以毫无问题地转换为 Shift-JIS()。82 c5

在 PHP 中,必须安装扩展 intl,然后您可以使用 normalizer_normalize() - 然后该函数的结果可以完全转换为 Shift-JIS。