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ş�

我的错误是什么?

你应该使用多字节 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);;

?>

Ref | Demo

首先,总是将您的问题分解成更小的部分,看看哪里出了问题:

$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 之类的函数不会以任何有意义的方式计算 "characters"。所以 substr($string, 0, 14) 只取字符串的前 14 个字节,在这种情况下,它恰好拆分了一个 "character",它使用 UTF-8 编码为多个字节。

最常见的解决方案是使用 mb_substr("mbstring" PHP 扩展的一部分),它根据某种编码计算 "characters":

$string = mb_substr($string, 0, 14, 'UTF-8');
echo $string, "\n"; 
// Şelamiİnnşşasd

请注意,这将 运行cate 到 14 Unicode 代码点,因此如果使用"combining diacritic".

在某些情况下,另一种选择是使用 grapheme_substr("intl" 扩展的一部分),它在 "graphemes" 上拆分,这大致是人们会想到的作为 "character" 或 "letter"。在这种情况下,它给出相同的结果:

$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ë