strlen() 回傳的是位元組數,而 mb_strlen() 回傳的是字元數。在 UTF-8 編碼下,中文字佔 3 位元組,英文佔 1 位元組,兩者差異極大。
$str = '中文a字1符'; // 4 中文 + 2 英數 = 6 字元 echo "strlen: " . strlen($str) . "\n"; // 14 (3×4 + 1×2) echo "mb_strlen UTF-8: " . mb_strlen($str, 'UTF-8') . "\n"; // 6 echo "mb_strlen GBK: " . mb_strlen($str, 'GBK') . "\n"; // 8 (2×4 + 1×2) echo "mb_strlen GB2312:" . mb_strlen($str, 'GB2312') . "\n"; // 10
$displayWidth = (strlen($str) + mb_strlen($str, 'UTF-8')) / 2; // (14 + 6) / 2 = 10
原理:UTF-8 中文 3 bytes、英文 1 byte →bytes + chars = 3C + E + C + E = 4C + 2E,除以 2 得2C + E即顯示寬度。
mb_strlen($str, 'UTF-8')mb_internal_encoding() 設定的內部編碼extension=mbstring(php.ini 中取消註解)| 需求 | 建議函式 |
|---|---|
| 截取前 N 個字元(中英同算 1) | mb_substr($str, 0, $n, 'UTF-8') | 截取前 N 個顯示寬度 | 自寫函式逐字累加寬度 |
| 驗證字串長度限制(資料庫 VARCHAR 長度以位元組計) | strlen($str) <= $maxBytes |
| 驗證使用者可見長度(如暱稱 10 字) | mb_strlen($str, 'UTF-8') <= 10 |
strlen() 是 O(1)(直接讀取結構體長度),極快mb_strlen() 需掃描整字串解碼,O(n),大量處理時可快取結果preg_match('/^[\x00-\x7F]*$/', $str) 判斷