Неверный вывод при использовании индексации массива в строке UTF-8 - PullRequest
14 голосов
/ 11 июня 2011

Я столкнулся с проблемой при использовании строки UTF-8. Я хочу прочитать один символ из строки, например:

$string = "üÜöÖäÄ";
echo $string[0];

Я ожидаю увидеть ü, но я получаю - почему?

1 Ответ

28 голосов
/ 11 июня 2011

Используйте mb_substr($string, 0, 1, 'utf-8'), чтобы получить символ.

В вашем коде происходит следующее: выражение $string[0] получает первый байт кодированного в UTF-8 представления вашегострока, потому что строки PHP фактически являются массивами байтов (PHP не распознает внутренне кодировки).

Поскольку первый символ в вашей строке состоит из более чем одного байта ( правила кодирования UTF-8 ), вы фактически получаете только часть персонажа.Кроме того, эти правила делают байт, который вы извлекаете, недействительным, чтобы обозначать его как отдельный символ, поэтому вы видите знак вопроса.

mb_substr знает правила кодирования, поэтомуон не будет наивно возвращать вам только один байт;он получит столько, сколько необходимо для кодирования первого символа.

Вы можете видеть, что $string[0] возвращает вам только один байт с:

$string = "üÜöÖäÄ";
echo strlen($string[0]);

В то время как mb_substr возвращает васдва байта:

$string = "üÜöÖäÄ";
echo strlen(mb_substr($string, 0, 1, 'utf-8'));

И эти два байта фактически являются одним символом (для этого нужно использовать mb_strlen):

$string = "üÜöÖäÄ";
echo mb_strlen(mb_substr($string, 0, 1, 'utf-8'), 'utf-8');

НаконецКак указывает Marwelln ниже, ситуация становится более терпимой, если вы используете mb_internal_encoding, чтобы избавиться от избыточности 'utf-8':

$string = "üÜöÖäÄ";
mb_internal_encoding('utf-8');
echo mb_strlen(mb_substr($string, 0, 1));

Вы можете см. большинство из вышеперечисленных в действии .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...