php mb_strlen return value is weird
gb2312是双字节字符集,使用mb_strlen()检查单个汉字将返回2,但是对于另外2个字符,有时结果很奇怪,有人知道为什么吗? 如何获得正确的长度?
1 2 3 4 5 6 7 8
| <?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,您的文档非常有帮助,像我这样的人很少了解编码,应该阅读它。每个程序员绝对,绝对需要了解与文本一起使用的编码和字符集
-
$a="大";所在的文件的编码是什么?
-
如果您说字符串是在gb2312中编码的,那么实际上它需要在gb2312中编码...这应该很有趣:每个程序员绝对,肯定需要了解与文本配合使用的编码和字符集的知识
-
谢谢,在我来这里寻求帮助之前,我已经尝试过gb2312,euc-cn,hz,utf-8,latin1。
-
@ user995789:您的评论" utf-8,latin1,whatever"恰恰是造成您问题的原因。 您可以继续猜测并尝试广泛,或者(替代地)尝试了解更多并理解它。
您的字符串可能存储为UTF-8。
"大"的UTF-8代码是E5 A4 A7(根据此网页),因此:
1 2 3 4 5
| $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 |
这只是一个猜测,但如果以这种方式思考,对我来说完全有意义。您可能可以参考此维基百科页面。
如果您确实要测试,建议您创建一个以gb2312编码保存的单独文件,并使用fopen或其他方式读取它。然后,您将确保它采用所需的编码。
-
谢谢,我认为这是因为Euc_cn php支持的编码编码,如果使用" HZ",则mb_strlen()可以完美工作。
尝试将MB内部编码设置为UTF-8
http://www.php.net/manual/zh/function.mb-internal-encoding.php
-
我假设您输入的是UTF-8,但听起来好像一定不是。无论如何,听起来mb_ *没有为您的输入使用正确的编码。
-
抱歉,我现在看到您正在指定编码,无论如何我都会建议编码。
-
这对我有用,我试图获取像mb_strlen("") == 1这样的物理字符,并且达到了目的。
通过将$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('大')将为您提供字节数,因为它是一个简单的老式函数,对编码一无所知,只计算字节数。
底线是:您的期望是错误的,并且"大"的实际编码内容(无论您将源代码保存为什么)与您告诉mb_strlen的编码内容(gb2312 )。因此,mb_strlen无法正确执行其工作,并为您提供各种随机结果。
-
谢谢,非常详细的解释,我认为预设编码(通过mb_internal_encoding()或标头或)仅在mb_str(string,encoding)中省略第二个参数时才有效。如果设置了参数,则mb_strlen()将对字符串进行编码,然后计算其长度。我认为我的问题是因为使用GB2312编码,可能gb2312或EUC-CN并不是此功能的不错选择,HZ更稳定,还有另一个GB18030,但它适用于Php5.4 +,我没有检查。
-
您需要使用字符串实际所在的编码,而不是您想要的编码!
-
嗨,看完你的文件后,我发现我错了,谢谢。
我认为您必须使用utf-8而不是gb2312
尝试这个:
1 2 3 4 5 6 7 8
| <?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,
?> |