Я столкнулся с проблемой при использовании строки UTF-8. Я хочу прочитать один символ из строки, например:
$string = "üÜöÖäÄ"; echo $string[0];
Я ожидаю увидеть ü
, но я понимаю, почему?
Используйте 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));
Вы можете увидеть большую часть вышесказанного в действии .