首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 字符串長度計算:strlen vs mb_strlen 核心區別、中英混排占位計算、編碼陷阱全解析

     編輯:PHP 綜合知識

一句話總結

strlen 計算「字節數」,mb_strlen 計算「字符數」(需指定編碼)。中文在 UTF-8 佔 3 字節,GBK 佔 2 字節,英文均佔 1 字節。

函數簽名對比

// 核心函數(無需擴展)
int strlen(string $string)

// mbstring 擴展函數(需啟用 php_mbstring.dll / --enable-mbstring)
int mb_strlen(string $string, string $encoding = null)

實測對比(文件編碼 UTF-8)



為什麼會有差異?

實用技巧:計算中英混排「顯示寬度/占位」

場景:表格列寬、截取摘要、終端對齊。規則:中文寬度 2,英文/數字/標點寬度 1。

function str_display_width(string $str, string $encoding = 'UTF-8'): int {
    // 原理:總字節數 + 字符數 = (中文×3 + 英文×1) + (中文+英文) = 中文×4 + 英文×2
    // 顯示寬度 = 中文×2 + 英文×1 = (總字節數 + 字符數) / 2
    return (strlen($str) + mb_strlen($str, $encoding)) / 2;
}

$test = '中文a字1符';
echo "顯示寬度: " . str_display_width($test); // 10 (4×2 + 1 + 1)

截取中英混排字符串(不截半個漢字)

// mb_substr 按字符截取,安全
$summary = mb_substr($longText, 0, 50, 'UTF-8') . '...';

// 如果必須用 substr(字節截取),需配合檢測
function safe_substr($str, $len, $encoding = 'UTF-8') {
    if (mb_strlen($str, $encoding) <= $len) return $str;
    return mb_substr($str, 0, $len, $encoding) . '...';
}

常見陷阱與避坑指南

1. 忘記啟用 mbstring 擴展

; php.ini
extension=mbstring  ; 取消註釋
; Windows: extension=php_mbstring.dll

2. 不指定編碼依賴內部編碼

// ❌ 風險:內部編碼可能被 mb_internal_encoding() 修改
mb_strlen($str); 

// ✅ 顯式指定
mb_strlen($str, 'UTF-8');

3. 文件編碼與聲明不一致

  • PHP 文件保存為 UTF-8 無 BOM
  • HTML <meta charset="UTF-8">
  • 資料庫連接 SET NAMES utf8mb4
  • 三者統一,才能保證 strlen/mb_strlen 行為可預期

4. 陣列/對象傳入 strlen

strlen(['a', 'b']); // 警告:期望 string,返回 1 (Array 轉字符串)
mb_strlen(['a', 'b']); // 警告 + false

5. 統計字符頻次

// count_chars 僅支援單字節編碼
// 多字節編碼用:
preg_match_all('/./u', $str, $matches); // u 修飾符按 Unicode 字符匹配
$freq = array_count_values($matches[0]);

效能對比

  • strlen:C 級別極快,O(1) 返回已知字節長度(PHP 字符串結構存儲長度)
  • mb_strlen:需遍歷字節解碼統計字符數,O(n),慢約 5-10 倍
  • 高頻調用場景(如百萬級循環)優先用 strlen,僅在需字符數時用 mb_strlen

總結速查表

編碼中文字節數英文/數字字節數備註
UTF-831現代 Web 標準,支援全字符集
GBK/GB231221中文舊標準,不支援生僻字/Emoji
UTF-162 或 42Java/JS 內部編碼
需求推薦函數示例
獲取字節長度(存儲、傳輸、緩存 key)strlen()strlen($json)
獲取字符數(顯示、驗證、截取)mb_strlen($str, 'UTF-8')mb_strlen($username, 'UTF-8')
計算顯示寬度(終端、表格、PDF)(strlen + mb_strlen) / 2str_display_width($text)
安全截取mb_substr($str, 0, $len, 'UTF-8')mb_substr($title, 0, 30, 'UTF-8')
按字符遍歷preg_match_all('/./u', $str, $m)foreach ($m[0] as $char)...

結語

搞清「字節」與「字符」的區別,始終顯式指定 UTF-8 編碼,統一文件/數據庫/頁面編碼,即可徹底解決 PHP 字符串長度計算的所有疑難雜症。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved