将strpos与UTF-8字符串一起使用是安全的


Safe to use strpos with UTF-8 strings?

我有一堆具有不同字符集的字符串。$charset变量包含当前字符串的字符集。

$content = iconv($charset, 'UTF-8', $content);

这样,使用strposstrlensubstr等,而不是它们的多字节等价物,安全吗?我这么问是因为我也经常使用preg_match。因此,如果我使用PREG_OFFSET_CAPTURE来获得单词在字符串中的位置,我就不能将该值与mb_substr一起使用来删除单词之前的所有内容。

这完全取决于你想要做什么。核心strlen和类似的函数在字节上工作。他们接受并返回的每个数字都是一个字节计数或字节偏移量。mb_*函数对字符进行编码感知。他们接受并返回的所有数字都是字符计数或偏移量。

如果您有一种安全的方法来获取字符串中的字节偏移量("安全"表示偏移量不在多字节字符的中间),然后,例如,使用substr裁剪偏移量之前的所有内容,这会很好。例如:

$str     = '漢字';
$offset  = strpos($str, '字');
$cropped = substr($str, $offset);

工作良好。

然而,这不会起作用:

$cropped = substr($str, $offset, 1);

如果不冒剪切多字节字符的风险,就无法安全地剪切单个字节

像strlen()这样的函数计算字节,而不是字符。

有关详细信息,请参阅PHP手册中的注释:

注:

strlen()返回字符串中的字节数,而不是字符数。

如果您使用UTF-8,请使用mb_*函数,除非您启用了php.ini设置mbstring.func_overload来重载标准strops()、strlen()、substr()等函数。。。则strlen()将计数字符