首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 中文字串截取亂碼問題完整解決方案(支援 UTF-8 與 GB2312)

     編輯:PHP 相關知識

中文截取亂碼的主因在於多位元組編碼:UTF-8 中文字佔 3 位元組,GB2312 佔 2 位元組。若直接用 substr 按位元組截取,極易將一個中文字「切一半」,產生亂碼。本文提供三種解法,最後一種通用性最佳。

針對特定編碼的手動判斷法

GB2312 版(雙位元組)

function chinesesubstr($str, $start, $len) {
    $strlen = $start + $len;
    for ($i = $start; $i < $strlen;) {
        if (ord(substr($str, $i, 1)) > 0xa0) { // 中文
            $tmpstr .= substr($str, $i, 2);
            $i += 2;
        } else {
            $tmpstr .= substr($str, $i, 1);
            $i++;
        }
    }
    return $tmpstr;
}

UTF-8 版(三位元組)

function chinesesubstr($str, $start, $len) {
    $strlen = $start + $len;
    for ($i = $start; $i < $strlen;) {
        if (ord(substr($str, $i, 1)) > 0xa0) { // 中文
            $tmpstr .= substr($str, $i, 3);
            $i += 3;
        } else {
            $tmpstr .= substr($str, $i, 1);
            $i++;
        }
    }
    return $tmpstr;
}

缺點:需知道編碼,且無法處理混合編碼。

通用解法:正規表達式匹配字元(推薦)

此函式同時支援 UTF-8 與 GB2312,不需擔心編碼問題:

function cut_str($string, $sublen, $start = 0, $code = 'UTF-8') {
    if ($code == 'UTF-8') {
        $pa = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/";
        preg_match_all($pa, $string, $t_string);
        if (count($t_string[0]) - $start > $sublen) {
            return join('', array_slice($t_string[0], $start, $sublen)) . "…";
        }
        return join('', array_slice($t_string[0], $start, $sublen));
    } else { // GB2312/GBK
        $start *= 2;
        $sublen *= 2;
        $strlen = strlen($string);
        $tmpstr = '';
        for ($i = 0; $i < $strlen; $i++) {
            if ($i >= $start && $i < ($start + $sublen)) {
                if (ord(substr($string, $i, 1)) > 129) {
                    $tmpstr .= substr($string, $i, 2);
                } else {
                    $tmpstr .= substr($string, $i, 1);
                }
            }
            if (ord(substr($string, $i, 1)) > 129) $i++;
        }
        if (strlen($tmpstr) < $strlen) $tmpstr .= "…";
        return $tmpstr;
    }
}

使用範例

$str = "你好世界 Hello World";
echo cut_str($str, 6); // 輸出:你好世界…
echo cut_str($str, 6, 0, 'GB2312'); // 同樣正確

現代替代方案

PHP 5.4+ 可直接使用 mb_substr(需啟用 mbstring 擴充):

echo mb_substr($str, 0, 6, 'UTF-8'); // 簡潔可靠

建議專案統一使用 UTF-8 並善用 mb_* 函式庫,徹底避免編碼困擾。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved