我们知道在PHP中有两大类函数用来处理字符串的
1、str开头的
2、mb开头的函数
我们最先接触的是str函数,所以不可避免在工作中会优先使用str函数,但是仔细研究就会发现大部分str函数操作的是字节数组,虽然字符串也是由多个字节组成的字节数组,但是对于多字节的字符,在处理上却不是很好。
// utf-8编码
$string = 'rxy中国';
1、strlen — 获取字符串长度
实际上这个描述是错的,因为官方有一个提示
Note:
strlen() returns the number of bytes rather than the number of characters in a string.
所以strlen的真正描述是:获取字符串的字节长度。
echo strlen($string); // 9
在unicode字符集中utf-8编码规则下,一个中文占三个字节。
2、substr — 返回字符串的子串
它的真实含义是截取字符串对应的字节数组。
echo substr($string, 0, 4); // rxy�
因为在unicode字符集中找不到对应的字符,所以操作系统也就无法正常显示。
3、访问指定位上的字符
既然字符串是一个字节数组,那么也就可以以数组的方式访问某个字节元素了。
echo $string[0]; // r
echo $string[3]; // �
echo $string[4]; // �
echo $string[5]; // �
echo $string[3] . $string[4] . $string[5]; // 中
由以上三个例子可以看出,str系列函数是偏向于字节数组的操作,而不适合我们常用的场景,当然str还有一些函数就不存在这样的情况,比如
str_replace — 子字符串替换
单纯的匹配和替换,不用关心某个字符是不是多字节字符,因此不受影响。
以上列出的只是小部分函数,其他的str函数,根据其定义就可以判断出是否适合使用。
相比之下mb函数则更适合用作字符串处理。它使用unicode字符集为基准,以utf-8编码作为规则来处理字符串。
针对上面的问题,采用mb函数来处理:
//获取字符串长度
echo mb_strlen($string); // 5
//截取字符串
echo mb_substr($string, 0, 4); // rxy中
//获取指定位置上的字符
echo mb_substr($string, 0, 1) // r
echo mb_substr($string, 3, 1) // 中