是的,我知道。当我们使用多字节字符时,应该使用 mb_* 函数。但是当我们使用 strpos 时呢? 让我们看一下这段代码(保存为 utf-8)。
var_dump(strpos("My symbol utf-8 is the €.", "\xE2\x82\xAC")); // int(23)
使用 mb_strpos 与 strpos 有何区别?它们难道不是完成相同的工作吗? 毕竟,strpos 不就是在查找一个多字节字符串吗?那么为什么要使用 strpos?
是的,我知道。当我们使用多字节字符时,应该使用 mb_* 函数。但是当我们使用 strpos 时呢? 让我们看一下这段代码(保存为 utf-8)。
var_dump(strpos("My symbol utf-8 is the €.", "\xE2\x82\xAC")); // int(23)
使用 mb_strpos 与 strpos 有何区别?它们难道不是完成相同的工作吗? 毕竟,strpos 不就是在查找一个多字节字符串吗?那么为什么要使用 strpos?
对于UTF-8编码,匹配字节序列与匹配字符序列是完全相同的。
因此,它们都将在完全相同的位置找到针,但是mb_strpos
会在针前计算完整的UTF-8字节序列,而strpos
则计算任何字节。因此,如果您的字符串具有另一个多字节UTF-8序列,则结果将不同:
strpos("My symbolö utf-8 is the €.", "€") !== mb_strpos("My symbolö utf-8 is the €.", "€", 0, "UTF-8")
但是:
strpos("My symbol utf-8 is the €.", "€") === mb_strpos("My symbol utf-8 is the €.", "€", 0, "UTF-8")
strpos()
查找作为搜索词传递的字节序列。
mb_strpos()
做同样的事情,但它还尊重字符边界。strpos()
会在字符串中任何位置匹配字节序列。只有当字节序列表示完整字符集的有效集时,mb_strpos()
才会进行匹配。mb_strpos()
也会找到无效字符集。唯一的区别在于返回值和参数(字符而不是字节),但无效字符的处理方式是相同的。 - Danon我认为上述例子并不是完全透明的,可能会让一些用户感到困惑。
mb_string()
应该用于多字节编码,而什么是多字节编码,您可以在其他问题中解释,例如 这里。
最近我们主要使用 UTF 编码,如本例中的 UTF-8
(还有 UTF-16
),这是一种多字节字符集,然而通常我们只使用 ASCII 字符集(例如英语),对于它们,strpos
和 mb_strpos
的结果是相同的。
差异在于当我们使用多字节字符,即中文字符时可见。
echo mb_internal_encoding(); //UTF-8
echo strpos('我在买绿茶', '在'); //3
echo mb_strpos('我在买绿茶', '在'); //1
显然,这适用于中文字符,但也适用于表情符号,一些人可能不知道。
为了让您更好地了解它的工作方式,我将使用strlen()
和mb_strlen()
函数显示以下字符串的长度。
echo strlen('我在买绿茶'); //15
echo mb_strlen('我在买绿茶'); //5