php 8.1 中判断多字节字符串长度必须用 mb_strlen($str, 'utf-8'),显式指定编码;需先验证输入为合法 utf-8,数组需过滤非字符串元素,大文件应流式分块处理。

PHP 8.1 判断多字节字符串长度,核心就一条:用 mb_strlen($str, 'UTF-8'),显式传编码,不依赖内部设置。
必须显式指定 UTF-8 编码
PHP 8.1 中 mb_strlen() 的第二个参数不能省略。省略时会回退到 mb_internal_encoding(),而该值在 CLI 和 Web 环境中可能不一致,甚至未设置,导致结果不可靠。
- ✅ 正确写法:
mb_strlen($str, 'UTF-8') - ❌ 危险写法:
mb_strlen($str)或mb_strlen($str, null) - ⚠️ 注意:
mb_internal_encoding('UTF-8')只需在脚本开头设一次,不建议在循环或函数里反复调用
先确保输入是合法 UTF-8 字符串
非法编码的字符串传给 mb_strlen() 可能返回异常值(如 0)或触发静默截断。尤其来自表单、JSON、数据库的数据,需主动验证和清洗:
- 用
mb_check_encoding($str, 'UTF-8')检查是否真正为 UTF-8 - 若非 UTF-8,可用
mb_convert_encoding($str, 'UTF-8', 'auto')尝试转换('auto'包含 UTF-8、GBK、BIG5 等常见编码) - 对用户输入,建议配合
trim()和去除零宽字符(如preg_replace('/[\x{200B}-\x{200D}\x{FEFF}]/u', '', $str))
数组中混有非字符串元素?要先过滤
如果待测数据是数组(如 $_POST),不能直接对整个数组调用 mb_strlen() —— 它只接受字符串。PHP 8.1 对 strlen(null) 会抛 TypeError,更需谨慎:
- 逐个判断:
if (is_string($item)) { $len = mb_strlen($item, 'UTF-8'); } - 批量生成长度数组:
array_map(fn($v) => is_string($v) ? mb_strlen($v, 'UTF-8') : 0, $arr) - 避免用
array_map('mb_strlen', $arr)—— 遇到数字、null、数组会报错或返回 false
大文本不加载进内存也能估算长度
处理几 MB 以上的日志或用户上传文本时,file_get_contents() + mb_strlen() 容易内存溢出。可改用流式估算:
- 用
fstat($fp)['size']获取文件字节数,再按平均字节/字符系数折算(中英混排常用/ 2.5) - 真要精确计数:用
fopen()分块读取(如每次 8192 字节),对每块调用mb_strlen($chunk, 'UTF-8')累加,注意用mb_substr($chunk, 0, -1, 'UTF-8')自动剔除跨字节截断的不完整字符
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











