PHP和Unicode:Windows和Linux之间的奇怪之处

PHP和Unicode:Windows和Linux之间的奇怪之处,php,windows,linux,unicode,php-5.3,Php,Windows,Linux,Unicode,Php 5.3,看看IBM的,尤其是清单3和清单4 在Ubuntu Lucid上,我从代码中获得与IBM相同的输出,即: Здравсствуйте Array ( [1] => 65279 [2] => 1047 [3] => 1076 [4] => 1088 [5] => 1072 [6] => 1074 [7] => 1089 [8] => 1089 [9] => 1090

看看IBM的,尤其是清单3和清单4

在Ubuntu Lucid上,我从代码中获得与IBM相同的输出,即:

Здравсствуйте
Array
(
    [1] => 65279
    [2] => 1047
    [3] => 1076
    [4] => 1088
    [5] => 1072
    [6] => 1074
    [7] => 1089
    [8] => 1089
    [9] => 1090
    [10] => 1074
    [11] => 1091
    [12] => 1081
    [13] => 1090
    [14] => 1077
)
Здравсствуйте
然而,在Windows上,我得到了完全不同的响应

ðùð┤ÐÇð░ð▓ÐüÐüÐéð▓Ðâð╣ÐéðÁ
Array
(
    [1] => -131072
    [2] => 386138112
    [3] => 872677376
    [4] => 1074003968
    [5] => 805568512
    [6] => 839122944
    [7] => 1090781184
    [8] => 1090781184
    [9] => 1107558400
    [10] => 839122944
    [11] => 1124335616
    [12] => 956563456
    [13] => 1107558400
    [14] => 889454592
)
ðùð┤ÐÇð░ð▓ÐüÐüÐéð▓Ðâð╣ÐéðÁ
除了俄语字符(在UTF-32中)不在CMD.EXE shell中呈现(因为它们在UTF-32中而不是Windows自己的UTF-16中)之外,为什么字符值差异如此显著

function utf8_to_unicode_code($utf8_string)
{
    $expanded = iconv("UTF-8", "UTF-32", $utf8_string);
    return unpack("L*", $expanded);
}
这有两个错误:

  • 它使用“UTF-32”,这将在字符串的开头删除一个不需要的BOM表,这就是为什么会得到65279(0xFEFF BOM)。你不想让流浪的Bom在这个地方到处乱跑,制造麻烦

  • 它使用特定于机器的字节结尾(大写
    L
    ),而
    iconv
    可能与此不符。老实说,我没有料到它会在Windows框上发生冲突(因为不管操作系统如何,i386都是little endian),但很明显,它确实发生了冲突,因为您得到的值都是由反向字节顺序产生的

  • 最好明确说明这两个字节顺序,并避免使用BOM表。使用
    UCS-4LE
    作为编码,并使用
    V*
    解包。这同样适用于
    unicode\u-code\u-utf8


    也可以忽略清单6。像fi连字等省略号字符是一种“兼容性字符”,在现代Unicode和OpenType世界中我们不会使用它。字体可以为
    fi
    ..
    提供上下文选择,而不是要求我们篡改文本。

    +1用于捕获反向字节顺序值。我还在盯着看,想弄清楚那些数字是从哪里来的。绿色的大记号是给你的,@bobince。非常感谢。