[英]Php substr Utf-8 issue
当我运行这段代码
$string='<p>Şelamiİnnşşasdüğ213,123wqeq.weqw.rqasd</p><p>Şelamiİnnşşasdüğ213,123wqeq.weqw.rqasd</p><p>Şelamiİnnşşasdüğ213,123wqeq.weqw.rqasd</p>';
echo substr(strip_tags(trim(html_entity_decode($string, ENT_COMPAT, 'UTF-8'))), 0, 14);;
我得到这个结果。
Şelamiİnnş
我的错是什么?
首先,请始终将问题分解为更小的部分,以查看问题出在哪里:
$string=html_entity_decode($string, ENT_COMPAT, 'UTF-8');
echo $string, "\n";
$string = trim($string);
echo $string, "\n";
$string = strip_tags($string);
echo $string, "\n";
$string = substr($string, 0, 14);
echo $string, "\n";
如果运行该命令,将会发现问题与strip_tags
无关,而与substr
。
原因很简单:PHP中的字符串只是一系列字节;它只是一个字节。 诸如substr
函数不会以任何有意义的方式计算“字符”。 因此, substr($string, 0, 14)
只是获取字符串的前14个字节,在这种情况下,恰好使用UTF-8拆分了一个编码为多个字节的“字符”。
最常见的解决方案是使用mb_substr
(PHP扩展“ mbstring”的一部分),该mb_substr
根据某些编码对“字符”进行计数:
$string = mb_substr($string, 0, 14, 'UTF-8');
echo $string, "\n";
// Şelamiİnnşşasd
请注意,这将截断为14个Unicode代码点 ,因此,如果使用“组合变音符号”对字母进行重音编码 ,则仍然可以做一些奇怪的事情,例如将字母切成重音。
在某些情况下,一种替代方法是使用grapheme_substr
(“ intl”扩展名的一部分),它在“ graphemes”上分割,旨在大致地被人们认为是“字符”或“字母”。 在这种情况下,其结果相同:
$string = grapheme_substr($string, 0, 14, 'UTF-8');
echo $string, "\n";
// Şelamiİnnşşasd
但是在其他情况下,它可能不会:
$string = 'noël';
echo mb_substr($string, 0, 3, 'UTF-8'), "\n"; // noe
echo grapheme_substr($string, 0, 3), "\n"; // noë
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.