近日接手一个二开添加翻译插件的任务,加翻译插件前网页显示正常,加插件后部分网页前部显示正常,后部显示乱码,看起来与文本编码不正确差不多。一开始感觉有些无从下手,仔细浏览网页后发现,每次出现乱码前都有个不完整的文字,怀疑是文字截取错误造成了乱码。
打开源码,发现原代码中使用了substr函数来截取字符串。在php中,substr函数是严格按字节数来截取字符串,虽然一个中文字符为3个字节,如果仅以3的倍数来进行截取,字符串中一旦出现字母、数字等单字节字符而没有在截取前进行判断处理,就很容易造成出现截取到半个中文字符的情况。
例如如下代码,
$str="活泼枫叶6c的头条号";
echo substr($str,0,15);
运行的结果为
活泼枫叶6c?
虽然截取的15个字符,因为6c两个字符只占2个字节,打乱了字符串的规律,所以结果会出现半个字符。
说到这里,可能有些小伙伴会想在截取前先对字符串进行一下处理,或者自己写一个函数。其实大可不必这么麻烦,php已经为我们提供了解决方案。
1、按字符数量截取字符串的mb_substr
例如
$str="活泼枫叶6c的头条号";
echo mb_substr($str,0,7);
运行的结果为
活泼枫叶6c的
需要截取几个字,参数就写几个字,一目了然。
2、按字节截取字符串的mb_strcut
例如
$str="活泼枫叶6c的头条号";
echo mb_strcut($str,0,15);
运行结果为
活泼枫叶6c
可以看到,虽然mb_strcut也是按字节截取字符串,但它不会截断字符。
在PHP中,substr虽然用得很多,但要对中文字符串进行截取时,应根据需要选择mb_substr或mb_strcut,从而避免出现半个字符乱码的情况。