PHP и Unicode: странность между Windows и Linux - PullRequest
2 голосов
/ 04 октября 2010

Посмотрите на IBM Unicode для работающего программиста PHP , особенно листинги 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 (потому что они в UTF-32, а не в собственном UTF- Windows)16), почему значения символов отличаются так значительно?

1 Ответ

3 голосов
/ 04 октября 2010
function utf8_to_unicode_code($utf8_string)
{
    $expanded = iconv("UTF-8", "UTF-32", $utf8_string);
    return unpack("L*", $expanded);
}

Это делает две вещи неправильно:

  1. Используется «UTF-32», который отбрасывает нежелательную спецификацию в начале строки, поэтому вы получаете65279 (0xFEFF BOM).Вы не хотите, чтобы случайные спецификации висели вокруг места, вызывая проблемы.

  2. В нем используется машинная последовательность байтов (прописная L), с которой iconv вполне может не согласиться.Честно говоря, я бы не ожидал, что будет конфликтовать на Windows-боксе (поскольку i386 является прямым порядком байтов независимо от ОС), но, очевидно, так оно и есть, поскольку полученные значения - это то, что нужнорезультат обратного порядка следования байтов.

Лучше явно указать оба порядка байтов и избегать спецификации.Используйте UCS-4LE в качестве кодировки и распакуйте с V*.То же самое относится и к unicode_code_to_utf8.

. Также не обращайте внимания на листинг 6. Символ многоточия, например, лигатура и т. Д., Является символом совместимости, который мы бы не использовали в современном Unicode-and-Мир OpenType.Шрифт должен предоставить контекстные альтернативы для fi или ..., если он этого хочет, вместо того, чтобы требовать от нас искажать текст.

...