在UTF-8字符串上使用数组索引时输出错误

boz*_*ozd 15 php arrays string utf-8 char

使用UTF-8字符串时遇到问题.我想从字符串中读取单个字符,例如:

$string = "üÜöÖäÄ";
echo $string[0];
Run Code Online (Sandbox Code Playgroud)

我期待看到ü,但我得到 - 为什么?

Jon*_*Jon 29

使用mb_substr($string, 0, 1, 'utf-8')来获取字符,而不是.

代码中发生的是表达式$string[0]获取字符串的UTF-8编码表示的第一个字节,因为PHP字符串实际上是字节数组(PHP不在内部识别编码).

由于字符串中的第一个字符由多个字节组成(UTF-8编码规则),因此实际上只能获得字符的一部分.此外,这些规则使您检索的字节无效,可以单独作为字符,这就是您看到问号的原因.

mb_substr知道编码规则,所以它不会天真地回馈一个字节; 它将获得编码第一个字符所需的数量.

你可以看到,$string[0]它只返回一个字节:

$string = "üÜöÖäÄ";
echo strlen($string[0]);
Run Code Online (Sandbox Code Playgroud)

虽然mb_substr给你两个字节:

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

而这两个字节实际上只是一个字符(你需要使用mb_strlen它):

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

最后,正如Marwelln在下面指出的那样,如果您使用mb_internal_encoding摆脱'utf-8'冗余,情况就会变得更加容忍:

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

你可以看到上面的大部分内容.

  • 我建议使用http://www.php.net/manual/en/function.mb-internal-encoding.php,这样你就不需要在每个`mb_`函数中指定'utf-8'. (2认同)