php 8.2 应使用 mb_strlen($str, 'utf-8') 获取中英文混合字符串的真实字符数,避免 strlen() 的字节计数错误;含 emoji 时可用 grapheme_strlen();需先 trim() 和清理控制字符,并验证 utf-8 编码。

PHP 8.2 判断中英文混合字符串长度,核心原则是:**按“用户感知的字符数”计,而非字节数**。UTF-8 下,“你好”是 2 个字符,不是 6 字节;“Hello”是 5 个字符,不是 5 字节——但两者在视觉和业务规则中都算“1 位 = 1 字符”。直接用 strlen() 会严重高估中文长度,必须改用多字节安全函数。
统一使用 mb_strlen() 并显式指定编码
这是最直接、最可靠的方式。PHP 8.2 默认启用 mbstring 扩展(若未启用,需确认 extension=mbstring 在 php.ini 中已开启):
-
mb_strlen($str, 'UTF-8')返回真实 Unicode 字符数,中英文均按 1 个字符计 - 务必显式传入
'UTF-8',避免依赖mb_internal_encoding()的不确定状态 - 示例:
mb_strlen('Hi你好123', 'UTF-8')→ 返回 7(2 英文 + 2 中文 + 3 数字)
处理含 emoji 或复杂 Unicode 字符的场景
普通 mb_strlen() 对 ZWJ 序列(如 ??)、变体选择符、组合字符等仍按码点计数,可能与视觉长度不一致。如需更贴近“人眼所见”的长度(例如评论显示截断),可改用:
-
grapheme_strlen($str):按 Unicode 图形簇(grapheme cluster)计数,"??"算 1,"é"(e + ◌́)也算 1 - 该函数在 PHP 8.2 中默认可用,无需额外扩展
- 注意:性能略低于
mb_strlen(),高频调用时需权衡
校验前务必清洗输入
用户粘贴内容常含隐藏字符(零宽空格 \xe2\x80\x8b、BOM、软连字符等),导致 mb_strlen() 结果虚高:
- 先用
trim()去首尾空白 - 再用正则清理控制字符:
preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]/u', '', $str) - 或强制标准化:
mb_convert_encoding($str, 'UTF-8', 'UTF-8')(可修复非法序列) - 验证是否真为 UTF-8:
mb_check_encoding($str, 'UTF-8'),非 UTF-8 时先转换
避免常见错误写法
这些方式在 PHP 8.2 中依然不适用或存在隐患:
-
strlen($str):对中文返回字节数(如 "你好"→6),完全不可用于业务长度判断 -
isset($str[5])类字节偏移判断:UTF-8 下可能落在字符中间,引发乱码或逻辑错乱 - 正则
preg_match('/^.{10}$/u', $str):虽加u修饰符,但无法处理图形簇,且性能差、易出边界问题 -
array_map('mb_strlen', $arr)直接用于数组:需先is_string()过滤,否则对数字/null 报 warning
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











