PHP strlen() 返回位元組數,mb_strlen() 返回字元數。中文 UTF-8 下一字佔 3 位元組,直接用 strlen() 比較會產生誤導性結果。
$str1 = 'Hello'; // 5 字元,5 位元組
$str2 = '你好世界'; // 4 字元,12 位元組 (UTF-8)
echo strlen($str1); // 5
echo strlen($str2); // 12 ← 陷阱!
echo mb_strlen($str2, 'UTF-8'); // 4 ← 正確字元數
/**
* 計算兩字串字元數差異(絕對值)
* @param string $str1
* @param string $str2
* @param string $encoding
* @return int
*/
function strLengthDiff(string $str1, string $str2, string $encoding = 'UTF-8'): int {
$len1 = mb_strlen($str1, $encoding);
$len2 = mb_strlen($str2, $encoding);
return abs($len1 - $len2);
}
// 使用
echo strLengthDiff('Hello', '你好世界'); // |5 - 4| = 1
echo strLengthDiff('PHP', 'PHP'); // 0
// 原始:用 strlen() 且無編碼參數
function str_compare_length($str1, $str2) {
$len1 = strlen($str1);
$len2 = strlen($str2);
return abs($len1 - $len2);
}
// 問題:中文長度會被誤判為 3 倍
// 修正:改用 mb_strlen()
| 場景 | 推薦函數 | 說明 |
|---|---|---|
| 純 ASCII / 位元組運算 | strlen() | 快、無多位元組問題 |
| 多語言字元計數 | mb_strlen($str, 'UTF-8') | 正確字元數,指定編碼 |
| 資料庫欄位長度驗證 | mb_strlen() | VARCHAR(n) 指字元數 |
| 檔案/網路傳輸大小 | strlen() | 實際位元組數 |
| 正則表達式 | mb_strlen() / u 修飾符 | preg_match('/pattern/u', $str) |
if (!extension_loaded('mbstring')) {
die('mbstring extension required. Install: apt-get install php-mbstring / Enable in php.ini');
}
// 設定內部編碼(影響 mb_* 函數預設值)
mb_internal_encoding('UTF-8');
// 100 萬次呼叫測試
strlen() ~ 0.08 秒
mb_strlen() ~ 0.15 秒 // 稍慢但正確
差異微小,正確性優先。所有面向使用者的字串長度計算,一律用 mb_strlen()。
mb_strlen(),指定 UTF-8 編碼strlen(),僅限二進位/ASCII 場景strLengthDiff() 統一專案標準,避免混用mb_internal_encoding('UTF-8'),減少重複參數字串長度看似基礎,卻是多語言專案 Bug 高發區。建立「字元數優先、位元組數特定場景」的編碼共識,能避免無數顯示截斷、驗證失效、資料庫截斷等棘手問題。