strlen() 回傳的是位元組數,非字元數。編碼不同,一個中文字佔的位元組數不同:
因此 strlen("三知開發網") 在 UTF-8 下得到 15(5 × 3),而非 5。
mb_strlen($str, 'UTF-8') 依指定編碼計算字元數,中英皆算 1。
<?php
$str = "三知sunchis開發網"; // 5 中 + 7 英 = 12 字元
echo strlen($str); // 22 位元組 (5×3 + 7×1)
echo mb_strlen($str, "UTF-8"); // 12 字元
?>
若伺服器未啟用 php_mbstring.dll,可用數學關係反推:
$bytes = strlen($str); // 總位元組數
$chars = mb_strlen($str, 'UTF-8'); // 總字元數(需 mbstring)
// 假設只有中英混排,中文佔 3 位元組,英文佔 1 位元組
// 實際中文字數 = ($bytes - $chars) / 2
// 實際英文字數 = $chars - 中文字數
原文提供的公式 ($bytes + $chars) / 2 在純中英混排 UTF-8 下可得正確總字元數(含中文按 1 算、英文按 1 算)。
| 情境 | 建議做法 |
|---|---|
| 表單驗證「最多 20 字」 | 用 mb_strlen($input, 'UTF-8') <= 20,並明確指定編碼。 |
| 資料庫欄位長度 VARCHAR(100) | MySQL utf8mb4 下 VARCHAR 計算字元數,CHAR_LENGTH() 回傳字元數,與 mb_strlen 一致。 |
| 截取字串 | 用 mb_substr($str, 0, 20, 'UTF-8'),避免截斷多位元組字元產生亂碼。 |
| 未安裝 mbstring | 安裝擴充:extension=mbstring(php.ini),或用 Composer 套件 php-mbstring/polyfill。 |
<meta charset="UTF-8">。SET NAMES utf8mb4 / PDO DSN charset=utf8mb4。mb_internal_encoding('UTF-8') 設定內部編碼,省略 mb_strlen 第二參數。