登陆 注册

php含中文字符串截取问题与方案

守望者 2020-03-31 251人围观 ,发现1个评论 php

在php中当我们截取包含有中文的string字符串或者说中英文混合字符串的时候可能会看到截取后的字符串出现了乱码。


问题描述:


例如,下面这个,我们想要截取字符串$a的前三个字符,然后,打印时出现了乱码:

从表面上看,我们的函数调用并没有问题,那么为什么会出现这个问题呢?


$a = "ab你好";

echo substr($a,0,3); //输出:ab�



分析原因:


    substr($str,$start,$len):


    这里的 $start代表要截取字符串的开始下标位置;$len代表要截取字符串的长度,这个我们都知道。


      然而,大部分都忽视了一个问题,那就是他们的单位是字节。

这就意味着如果字符串只包含数字和字母,那么字符串截取不会出现什么问题。

因为几乎所有编码里面一个数字或字母只占一个字节大小,这个时候按字节截取与按字符截取效果是一样的。


      而当字符串中包含中文时,那么情况就不一样了,一个中文字符不管是在utf编码中还是在gbk编码中都要占用一个以上的字节大小。

此时当我们再用相同的方法(substr()) 截取n个汉字的时候,并没有截取完整,所以就出现了乱码。

比如我们想要截取两个汉字,参数len=2, 那么实际结果只截取了“半个汉字”(gbk编码中汉字占2个字节)或者“不到半个汉字”(utf-8编码中汉字占3个字节),

这种情况下就会出现乱码,即使不出现乱码,恰巧截取整数个汉字,我们所得到的汉字的数量也比原本想要截取的汉字少些(自己梳理一下)。



解决方案:


mb_substr($str,$start,$len,$encoding);


这个函数与substr()函数相比,他的单位是字符,

这就意味着,不管字符串里面包含数字,字母,或者汉字,这里的参数$len始终代表字符数,而不是字节数。

最后一个参数,$encoding使我们想要使用的编码,选择utf-8或者gbk都可以,不过utf-8涵盖的字符集更广些。

需要注意的是:$encoding参数必须要带上,否则函数将会按照系统内置默认编码操作,可能会有意想不到的“惊喜”出现。


相似的,mb_strlen()也比strlen()在对字符的操作上有异曲同工之妙。


最后,问题已经解决:

$a = "12你好";

echo mb_substr($a,0,3,"utf-8"); // 输出12你好


   转载请注明文本链接:https://tufeng.xyz/php/35.html,谢谢合作!

已有1条评论
  • 2020-04-03 22:24:22

    以前总是知其然,今天终于知其所以然了

请关注微信公众号
微信二维码