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

PHP mb_substr 字符與字節誤區:UTF-8 下中文截取長度計算詳解

     編輯:PHP 相關知識

核心結論

mb_substr($str, $start, $length, $encoding) 的 $length 參數是「字符數」,而非「字節數」。無論編碼為 UTF-8 (中文 3 字節) 或 GBK (中文 2 字節),mb_substr($str, 0, 2, 'UTF-8') 都返回前 2 個字符。

代碼驗證

$str = "中華人民共和國"; // 7 個中文字符

// UTF-8 環境
echo "UTF-8:\n";
echo mb_substr($str, 0, 2, 'UTF-8') . "\n"; // 中華 (2字符)
echo mb_substr($str, 0, 3, 'UTF-8') . "\n"; // 中華人 (3字符)
echo "字節長度: " . strlen($str) . "\n";    // 21 字節 (7*3)

// GBK 環境 (需文件保存為 GBK 或 iconv 轉換)
$gbkStr = iconv('UTF-8', 'GBK', $str);
echo "\nGBK:\n";
echo mb_substr($gbkStr, 0, 2, 'GBK') . "\n"; // 中華 (2字符)
echo "字節長度: " . strlen($gbkStr) . "\n";  // 14 字節 (7*2)

// 不指定編碼 (使用 mbstring.internal_encoding)
mb_internal_encoding('UTF-8');
echo "\n無編碼參數 (internal=UTF-8):\n";
echo mb_substr($str, 0, 2) . "\n"; // 中華

常見誤區對比

誤區正確理解
以為 $length 是字節數是字符數 (Code Points)
以為 UTF-8 中文佔 3 字節所以 length=6 才能取 2 個字length=2 即可取 2 個字
混用 substr (字節截取) 導致中文截半多字節編碼必須用 mb_substr
以為 mb_substr 會自動補全截斷的字符不會,嚴格按字符邊界截取

substr vs mb_substr

$str = "abc中文";
// substr (字節截取)
echo substr($str, 0, 5) . "\n"; // abc中 (第 5 字節截斷「中」的第一字節,顯示亂碼)
// mb_substr (字符截取)
echo mb_substr($str, 0, 5, 'UTF-8') . "\n"; // abc中文 (前 5 字符)

實用封裝:安全截取並添加省略號

function mbTruncate($str, $maxLen, $suffix = '...', $encoding = 'UTF-8') {
    $strLen = mb_strlen($str, $encoding);
    if ($strLen <= $maxLen) return $str;
    return mb_substr($str, 0, $maxLen - mb_strlen($suffix, $encoding), $encoding) . $suffix;
}

echo mbTruncate("這是一個很長的標題需要截取", 10); // 這是一個很長的...
echo mbTruncate("Short", 10); // Short

性能提示

  • mb_substr 需掃描字節確定字符邊界,極長字符串 (MB 級) 反複調用較慢。
  • 大量截取時,可先 mb_strlen 判斷是否需要截取。
  • PHP 7.2+ mb_substr 已優化,一般場景無性能瓶頸。

總結

記住:**mb_* 系列函數參數均以「字符」為單位**。只需設置正確的編碼 (或 mb_internal_encoding),即可正確處理多語言文本,無需手動計算字節數。

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