PHP中 trim 會導致亂碼的原因

運行以下代碼

$tag = "互聯(lián)網(wǎng)產(chǎn)品、";
$text = rtrim($tag, "、");
print_r($text);

我們可能以為會得到的結(jié)果是互聯(lián)網(wǎng)產(chǎn)品,實際結(jié)果是互聯(lián)網(wǎng)產(chǎn)?。為什么會這樣呢?

原理

trim 函數(shù)文檔

string trim ( string $str [, string $character_mask = " \t\n\r\0\x0B" ] )

該函數(shù)不是多字節(jié)函數(shù),也就是說,漢字這樣的多字節(jié)字符,會拿其頭或尾的單字節(jié)來和后面的$character_mask對應的char數(shù)組進行匹配,如果在后面的數(shù)組中,則刪掉,繼續(xù)匹配。比如:

echo ltrim("bcdf","abc");  // df

如下面的 demo 中的函數(shù)string_print_char所示:
、0xe3 0x80 0x81三字節(jié)組成,
0xe5 0x93 0x81三字節(jié)組成。
所以在執(zhí)行rtrim的時候,通過字節(jié)比對,會將0x81去掉,導致了最后出現(xiàn)了亂碼。

解決方案

封裝方法:
public static function mb_rtrim($string, $trim, $encoding)
{
    $mask = [];
    $trimLength = mb_strlen($trim, $encoding);
    for ($i = 0; $i < $trimLength; $i++) {
        $item = mb_substr($trim, $i, 1, $encoding);
        $mask[] = $item;
    }

    $len = mb_strlen($string, $encoding);
    if ($len > 0) {
        $i = $len - 1;
        do {
            $item = mb_substr($string, $i, 1, $encoding);
            if (in_array($item, $mask)) {
                $len--;
            } else {
                break;
            }
        } while ($i-- != 0);
    }

    return mb_substr($string, 0, $len, $encoding);
}

mb_internal_encoding("UTF-8");
$tag = "互聯(lián)網(wǎng)產(chǎn)品、";
$encoding = mb_internal_encoding();
print_r(mb_rtrim($tag, "、",$encoding));

參考文檔:
https://www.php.cn/php-weizijiaocheng-380613.html

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容