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

PHP 檢測字串中中文字符數量:mb_strlen 與自定義函數實現詳解

     編輯:PHP 相關知識

前言:為什麼需要專門計算中文字符?

在 PHP 開發中,獲取字串長度是常見需求。對於純英文字串,strlen() 即可滿足需求,因為每個英文字符佔用 1 個位元組。但當字串包含中文字符時,情況就變得複雜:UTF-8 編碼下,一個中文字符通常佔用 3 個位元組;GBK 編碼則佔用 2 個位元組。若直接使用 strlen(),得到的將是位元組數而非字符數,導致邏輯錯誤。

方案一:使用 mb_strlen(推薦)

PHP 的 mbstring 擴展提供了 mb_strlen() 函數,可正確處理多位元組字符。這是最簡單、最高效的方案:

$len = mb_strlen("你是我的小蘋果", "utf-8"); // 返回 7

只需指定字串與編碼(如 UTF-8、GBK),即可獲得準確的字符數。生產環境強烈建議啟用 mbstring 擴展。

方案二:無 mbstring 擴展時的自定義實現

若環境未安裝 mbstring,可根據字符編碼特性自行實現計數邏輯。核心原理:

  • ASCII 字符(英文、數字、符號)佔 1 位元組,碼值 < 0x80 (128)
  • 非 ASCII 字符(中文等)佔多位元組,首位元組碼值 ≥ 0x80
  • UTF-8 編碼中文字符佔 3 位元組,GBK 編碼佔 2 位元組

自定義函數實現

<?php
function mbstrlen($str, $encoding = "utf8") {
    $len = strlen($str);
    if ($len === 0) return 0;

    $encoding = strtolower($encoding);
    // 根據編碼確定每個中文字符佔用的位元組數
    if ($encoding === "utf8" || $encoding === "utf-8") {
        $step = 3;
    } elseif ($encoding === "gbk" || $encoding === "gb2312") {
        $step = 2;
    } else {
        return false; // 不支持的編碼
    }

    $count = 0;
    for ($i = 0; $i < $len; $i++) {
        $count++;
        // 遇到非 ASCII 字符,跳過後續位元組
        if (ord($str[$i]) >= 0x80) {
            $i += $step - 1; // -1 抵消 for 循環的 $i++
        }
    }
    return $count;
}

// 測試
echo mbstrlen("你是我的小蘋果"); // UTF-8 環境下輸出 7
echo mbstrlen(iconv("utf-8", "gbk", "你是我的小蘋果"), "gbk"); // GBK 輸出 7
?>

關鍵點解析

  • ord() 函數:獲取字符的 ASCII 碼值,用於判斷是否為多位元組字符的首位元組
  • 步進邏輯:發現首位元組碼值 ≥ 0x80 時,根據編碼跳過對應位元組數(UTF-8 跳 3 位元組,GBK 跳 2 位元組)
  • 編碼一致性:字串實際編碼必須與傳入的 $encoding 參數匹配,否則計數錯誤

進階建議與注意事項

1. 優先使用 mbstring:自定義函數僅適用於 UTF-8/GBK 等固定寬度編碼,無法處理 UTF-8 中佔 4 位元組的 Emoji 等字符,也不支援 Big5 等其他編碼。

2. 編碼轉換謹慎:示例中使用 iconv() 轉換編碼僅為演示,實際項目中應統一使用 UTF-8,避免編碼轉換導致的資料損壞。

3. 效能考量:自定義函數需逐位元組遍歷,長字串效能遠低於 C 實現的 mb_strlen()。

4. 現代 PHP 最佳實踐:PHP 7.2+ 內建 mbstring,若仍需相容舊環境,建議使用 symfony/polyfill-mbstring 等 Polyfill 庫,而非自行實現。

總結

計算含中文的字串長度,首選 mb_strlen()。理解底層原理(位元組結構、編碼規則)有助於排查編碼問題,但在生產代碼中應依賴成熟擴展或 Polyfill,確保正確性與效能。

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