在 PHP 開發中,獲取字串長度是常見需求。對於純英文字串,strlen() 即可滿足需求,因為每個英文字符佔用 1 個位元組。但當字串包含中文字符時,情況就變得複雜:UTF-8 編碼下,一個中文字符通常佔用 3 個位元組;GBK 編碼則佔用 2 個位元組。若直接使用 strlen(),得到的將是位元組數而非字符數,導致邏輯錯誤。
PHP 的 mbstring 擴展提供了 mb_strlen() 函數,可正確處理多位元組字符。這是最簡單、最高效的方案:
$len = mb_strlen("你是我的小蘋果", "utf-8"); // 返回 7
只需指定字串與編碼(如 UTF-8、GBK),即可獲得準確的字符數。生產環境強烈建議啟用 mbstring 擴展。
若環境未安裝 mbstring,可根據字符編碼特性自行實現計數邏輯。核心原理:
<?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
?>
$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,確保正確性與效能。