mb_strlen 返回字符数而 strlen 返回字节数,UTF-8 中一个汉字占3字节但算1字符;未指定编码或编码不匹配会导致 mb_substr 乱码;mb_detect_encoding 不可靠,应明确源头编码并用 mb_check_encoding 验证。
因为 strlen 按字节计数,而中文、日文等多字节字符(如 UTF-8 下的汉字)通常占 3 个字节,strlen 就会把一个汉字算成 3;mb_strlen 按字符计数,默认使用当前 mb_internal_encoding() 编码(通常是 UTF-8),所以一个汉字算 1。
常见错误:用 strlen 截取

echo mb_internal_encoding(); // 应为 UTF-8
mb_strlen($str, 'UTF-8')
mb_strlen(mb_convert_encoding($str, 'UTF-8', 'GBK'), 'UTF-8')
根本原因是没传编码参数,或编码与实际不符。PHP 7.2+ 默认使用 mb_internal_encoding(),但旧版本或某些 SAPI(如 CLI)可能默认是 ISO-8859-1,导致 mb_substr($str, 0, 5) 拿到半个 UTF-8 字节序列,解码失败就变空或 。
mb_substr($str, 0, 5, 'UTF-8')
mb_substr($str, 0, 2, 'UTF-8') 取前两个汉字,不是前两个字节mb_detect_encoding 是启发式猜测,对短文本、纯 ASCII 或混合编码几乎必然误判。比如一段含中文的 JSON 字符串,可能被错判为 SJIS 或 EUC-JP,后续 mb_convert_encoding 就会把 UTF-8 字节当其他编码转,结果全乱。
mb_detect_encoding($str, ['UTF-8', 'GBK', 'BIG5'], true)
mb_check_encoding($str, 'UTF-8') 验证,返回 false 就说明不是合法 UTF-8,再考虑 fallback 处理常见于 Docker 环境、自编译 PHP 或某些云函数平台 —— 扩展虽已安装,但未启用或被禁用函数列表屏蔽。
php -m | grep mbstring或
var_dump(extension_loaded('mbstring'));disable_functions 里没禁用 mb_substr 等(查看 phpinfo() 中 “Disabled Functions” 行)php-mbstring 包(不止是 php 主包)php --ini 和 phpinfo() 分别确认
来电咨询