| 函數 | 返回值含義 | 編碼感知 | 適用場景 |
|---|---|---|---|
| strlen() | 字節數 | 無(二進制安全) | 二進制數據、ASCII 字符串、內存佔用計算 |
| mb_strlen() | 字符數 | 有(需指定或 mb_internal_encoding) | 多字節字符串(中文、日文、Emoji 等)顯示長度、截取、驗證 |
<?php $str = '中文a字1符'; // UTF-8 編碼文件 echo 'strlen: ' . strlen($str) . PHP_EOL; // 14 (中文3字節×4 + 英文1字節×2) echo 'mb_strlen UTF-8: ' . mb_strlen($str, 'UTF-8') . PHP_EOL; // 6 (6個字符) echo 'mb_strlen GBK: ' . mb_strlen($str, 'GBK') . PHP_EOL; // 8 (GBK中文2字節×4 + 英文1字節×2) echo 'mb_strlen GB2312: '. mb_strlen($str, 'GB2312') . PHP_EOL; // 10 (GB2312擴展字符差異) // 內部編碼 echo 'internal_encoding: ' . mb_internal_encoding() . PHP_EOL; // 通常為 UTF-8
function visualWidth(string $str): int {
// 假設 UTF-8 編碼
$charCount = mb_strlen($str, 'UTF-8');
$byteCount = strlen($str);
// 中文字符在 UTF-8 佔 3 字節,英文佔 1 字節
// 視覺寬度 = (字節數 - 字符數) / 2 * 2 + 字符數 (簡化公式)
// 更精確:遍歷字符判斷東亞寬度
$width = 0;
for ($i = 0; $i < $charCount; $i++) {
$char = mb_substr($str, $i, 1, 'UTF-8');
$width += (preg_match('/^[\x{4e00}-\x{9fff}\x{3000}-\x{303f}\xff00-\xffef]$/u', $char)) ? 2 : 1;
}
return $width;
}
// 測試
echo visualWidth('中文a字1符'); // 10
VARCHAR(100) 以字符為單位(取決於字符集),用 mb_strlen 驗證;VARBINARY(100) 以字節為單位,用 strlen。substr 處理多字節字符串,必須用 mb_substr($str, 0, 10, 'UTF-8')。/u 修飾符支援 Unicode,如 preg_match('/^.{1,10}$/u', $str)。json_encode 輸出 UTF-8,strlen(json_encode($arr)) 計算傳輸字節數。extension=mbstring,Linux 編譯 --enable-mbstring。「存儲、傳輸、二進制 →
strlen;
顯示、截取、驗證、業務邏輯 →mb_strlen+ 顯式編碼。」