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

PHP UTF-8 中英文混合字符截取函數完整指南

     編輯:PHP 綜合知識

前言

在 PHP 開發中,處理 UTF-8 編碼的中英文混合字符串截取是常見需求。由於中文字符在 UTF-8 中佔 3 個位元組,英文字符佔 1 個位元組,直接使用 substr 會導致亂碼。本文將介紹幾種實用的截取方案,並分析其優缺點。

方案一:基於 ASCII 碼判斷的自定義函數

這是一種經典的不依賴擴展的實現方式,通過檢測字符的 ASCII 值來判斷字符類型:

  • ASCII ≥ 224:3 位元組字符(中文、日文等)
  • ASCII ≥ 192:2 位元組字符
  • ASCII 65-90:大寫字母(視為 1 個字符寬度)
  • 其他:小寫字母、半角符號(視為 0.5 個字符寬度)
function cut_str($sourcestr, $cutlength, $addstr = '...') {
    $returnstr = '';
    $i = 0;
    $n = 0;
    $str_length = strlen($sourcestr);

    while (($n < $cutlength) && ($i <= $str_length)) {
        $temp_str = substr($sourcestr, $i, 1);
        $ascnum = ord($temp_str);

        if ($ascnum >= 224) {
            $returnstr .= substr($sourcestr, $i, 3);
            $i += 3;
            $n++;
        } elseif ($ascnum >= 192) {
            $returnstr .= substr($sourcestr, $i, 2);
            $i += 2;
            $n++;
        } elseif ($ascnum >= 65 && $ascnum <= 90) {
            $returnstr .= substr($sourcestr, $i, 1);
            $i += 1;
            $n++;
        } else {
            $returnstr .= substr($sourcestr, $i, 1);
            $i += 1;
            $n += 0.5;
        }
    }

    if ($str_length > $cutlength) {
        $returnstr .= $addstr;
    }
    return $returnstr;
}

方案二:支援起始位置的 subUTF8str 函數

這個函數增加了 $start 參數,可從指定位置開始截取:

function subUTF8str($str, $start = 0, $length = 80) {
    $cur_len = 0;
    $all_len = strlen($str);

    if ($length > $all_len) return $str;

    // 定位起始位置
    for ($i = 0; $i < $all_len;) {
        if ($cur_len == $start) break;
        $i += (ord($str[$i]) > 127) ? 3 : 1;
        $cur_len++;
    }
    $start_pos = $i;

    // 截取指定長度
    $temp_pos = $cur_len;
    for (; $cur_len - $temp_pos < $length;) {
        if ($i >= $all_len) break;
        $i += (ord($str[$i]) > 127) ? 3 : 1;
        $cur_len++;
    }
    $end_pos = $i;

    return substr($str, $start_pos, $end_pos - $start_pos);
}

方案三:使用 PHP 內建 mbstring 擴展(推薦)

PHP 原生提供了多字節字符串處理函數族,這是最標準、最高效的方案:

  • mb_substr(string $str, int $start, int $length, string $encoding) - 字符串截取
  • mb_strlen(string $str, string $encoding) - 獲取字符串長度
  • mb_strcut、mb_strwidth 等輔助函數
// 簡單易用,自動處理編碼
$str = "123這是測試字符串";
echo mb_substr($str, 0, 4, 'UTF-8'); // 輸出:123這
echo mb_substr($str, 0, 10, 'UTF-8'); // 輸出:123這是測試

效能與選擇建議

方案優點缺點適用場景
自定義 ASCII 判斷無需擴展,可自定義字符寬度邏輯代碼複雜,需手動維護,效能一般無法安裝擴展的受限環境
subUTF8str支援起始位置截取同樣需手動處理位元組邏輯需要類似 substr 的完整功能時
mbstring 擴展官方標準、效能最佳、功能完整、無 Bug 風險需伺服器安裝擴展所有生產環境首選

最佳實踐總結

  1. 優先使用 mbstring:現代 PHP 環境幾乎都預裝,API 穩定可靠
  2. 設置內部編碼:在腳本開頭加入 mb_internal_encoding('UTF-8') 避免重複傳參
  3. 避免手工解析位元組:除非極特殊需求,否則不要重複造輪子
  4. 注意字符寬度差異:中文通常視為 2 個顯示寬度,英文為 1,前端對齊時需配合 CSS ch 單位或 monospace 字體

掌握正確的 UTF-8 字符串截取方法,能有效避免亂碼、截斷錯誤等常見問題,提升應用的國際化支援能力。

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