字串長度計算與截取是高頻操作,但多位元組字符(中文、日文等)在單字節函數下會產生錯誤結果,必須區分字節與字符長度。
| 功能 | 單字節函數 | 多位元組函數 | 說明 |
|---|---|---|---|
| 長度 | strlen() | mb_strlen() | 前者計算字節數,後者計算字符數 |
| 截取 | substr() | mb_substr() | 前者按字節截取,後者按字符截取 |
| 查找位置 | strpos() | mb_strpos() | 同理 |
<?php
echo strlen("www.example.com"); // 17 (ASCII 字符 1 字節)
echo strlen("中文"); // 6 (UTF-8 每字 3 字節)
?>
<?php
echo mb_strlen("www.example.com", 'UTF-8'); // 17
echo mb_strlen("中文", 'UTF-8'); // 2
?>
<?php
$a = "www.example.com";
echo substr($a, 0, 3); // "www"
echo substr($a, -3); // "com" (負數從末尾倒數)
$a = "中文測試";
echo substr($a, 0, 3); // "中" (UTF-8 中文佔 3 字節,可能截斷產生亂碼)
?>
<?php
$a = "中文測試";
echo mb_substr($a, 0, 2, 'UTF-8'); // "中文" (正確按字符截取)
echo mb_substr($a, 2, 2, 'UTF-8'); // "測試"
?>
mb_substr(string $string, int $start, int $length = null, string $encoding = mb_internal_encoding())
// $start: 起始位置 (0 索引,負數從末尾)
// $length: 截取長度,省略則截取到結尾
// $encoding: 字符編碼,建議顯式指定 'UTF-8'
<?php
function mb_cut($str, $length, $suffix = '...', $encoding = 'UTF-8') {
if (mb_strlen($str, $encoding) <= $length) return $str;
return mb_substr($str, 0, $length, $encoding) . $suffix;
}
echo mb_cut("這是一段很長的中文標題需要截取", 10); // "這是一段很長的中..."
?>
| 場景 | 錯誤做法 | 正確做法 |
|---|---|---|
| 中文截取 | substr($str, 0, 10) | mb_substr($str, 0, 10, 'UTF-8') |
| 長度判斷 | strlen($str) > 20 | mb_strlen($str, 'UTF-8') > 20 |
| 資料庫字段長度 | VARCHAR(20) 存 20 中文 | VARCHAR(60) 或用字符長度語義 |
掌握字節與字符的區別,正確選擇 mb_* 函數族,是處理多語言字串的基本功。