繁体   English   中英

PHP Substr Utf-8问题

[英]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ë

您应该使用多字节的substr()函数。

尝试

<?php
$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 mb_substr(strip_tags(trim(html_entity_decode($string,   ENT_COMPAT, 'UTF-8'))), 0, 14);;

?>

参考 | 演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM