php mb_strlen的返回值很奇怪

时间:2012-10-22 16:05:48

标签: php strlen

gb2312是一个双字节字符集,使用mb_strlen()检查单个中文字符将返回2,但是对于另外2个字符,有时结果很奇怪,有人知道为什么吗?我怎样才能得到合适的长度?

<?php
header('Content-type: text/html;charset=utf-8');//
$a="大";
echo mb_strlen($a,'gb2312'); // output 2
echo mb_strlen($a.$a,'gb2312'); // output 3 , it should be 4
echo mb_strlen($a.'a','gb2312'); // output 2, it should be 3
echo mb_strlen('a'.$a,'gb2312'); // output 3, 
?>

感谢deceze,您的文档非常有用,人们对像我这样的编码知之甚少应该阅读。What every programmer absolutely, positively needs to know about encodings and character sets to work with text

4 个答案:

答案 0 :(得分:4)

您的字符串可能存储为UTF-8。

"大"的UTF-8代码为E5 A4 A7(根据this webpage),所以:

$a       // 3 bytes, gb2312 -> 2 char (1 + 0.5)
$a . $a  // 6 bytes, gb2312 -> 3 char
$a . 'a' // 4 bytes, gb2312 -> 2 char
'a' . $a // 4 bytes, first byte is <128 so will be interpreted as one
         // single character, gb2312 -> 3 char

这只是猜测,但如果以这种方式思考,对我来说完全有意义。您可以参考this wikipedia page

如果你真的想测试,我建议你创建一个用gb2312编码保存的独立文件,并使用fopen或其他任何东西来阅读它。然后你会确定它是所需的编码。

答案 1 :(得分:2)

尝试将MB内部编码设置为UTF-8

/* Set internal character encoding to UTF-8 */
mb_internal_encoding("UTF-8");

http://www.php.net/manual/en/function.mb-internal-encoding.php

答案 2 :(得分:0)

我认为你必须使用utf-8代替gb2312

试试这个:

<?php
header('Content-type: text/html;charset=utf-8');//
$a="大";
echo mb_strlen($a,'utf8'); // output 1
echo mb_strlen($a.$a,'utf8'); // output 2 
echo mb_strlen($a.'a','utf8'); // output 2
echo mb_strlen('a'.$a,'utf8'); // output 2, 
?>

答案 3 :(得分:0)

通过将$a = "大";写入PHP文件,变量$a包含源代码文件中引号之间的任何字节序列。如果该源代码文件以UTF-8保存,则该字符串是表示字符“大”的UTF-8字节序列。如果源代码文件保存在GB2312中,则表示“大”的是GB2312字节序列。但是,保存在GB2312中的PHP文件实际上不会解析为有效的PHP,因为PHP需要ASCII兼容编码。

mb_strlen应该以指定的编码为您提供给定字符串中字符的数量。即mb_strlen('大', 'gb2312')期望字符串是GB2312字节序列表示,并且应该返回 1 。即使GB2312是双字节编码,你也不希望它返回2。 mb_strlen返回字符的数量

strlen('大')会给你 bytes 的数字,因为它是一个天真的旧式函数,它对编码一无所知,只计算字节数。

底线是:您的期望是错误的,并且您实际编码的“大”(无论您保存的源代码是什么)与您告诉mb_strlen编码的内容不匹配在(gb2312)。因此mb_strlen无法正确执行其工作,并为您提供不同的随机结果。