strlen() 返回字节长度而非字符数,处理中文、emoji 时易出错;mb_strlen($str, 'UTF-8') 才能正确获取字符数,且需确保 mbstring 扩展启用并统一编码。

strlen() 是 PHP 中判断字符串字节数的最常用函数
它返回的是字符串的字节长度,不是字符个数。对纯 ASCII 字符(如英文、数字、标点)来说,strlen() 和字符数一致;但遇到中文、emoji 或 UTF-8 多字节字符时,一个汉字通常占 3 字节,strlen() 就会返回 3 而不是 1。
常见错误现象:strlen("你好") 返回 6,误以为是“2 个字符”,结果在截取、验证长度限制(如用户名 ≤10 字符)时逻辑出错。
- 适用场景:校验 HTTP 请求头长度、文件路径字节数、二进制数据长度等底层操作
- 不适用场景:用户输入的昵称、标题、评论等需按“人眼可见字符数”限制的地方
- 性能高,无编码检测开销,PHP 内置 C 实现
mb_strlen() 才能正确获取 UTF-8 字符串的真实字符数
这是处理多语言内容的正确选择,必须指定编码参数,否则可能因默认编码不一致导致结果错误。在 UTF-8 环境下,务必写成 mb_strlen($str, 'UTF-8')。
常见错误现象:mb_strlen("a\u{1F600}你好")(含 emoji + 中文)返回 4,而 strlen() 返回 10;若漏写第二个参数,在某些服务器配置下可能按 ISO-8859-1 解析,中文全变成乱码或长度为 0。
立即学习“PHP免费学习笔记(深入)”;
- 使用前确认
mbstring扩展已启用(php -m | grep mbstring) - 在 composer 项目中,建议在启动时加
mb_internal_encoding('UTF-8')统一内部编码 - 比
strlen()稍慢,因需解析多字节序列,但对普通 Web 请求可忽略
用 mb_substr() 配合 mb_strlen() 做安全截断
直接用 substr() 截中文或 emoji 容易产生乱码,因为可能在某个 UTF-8 字节中间切断。必须用 mb_substr() 并传入相同编码。
示例:限制标题最多显示 15 个字符,超长加省略号:
$title = "PHP 字符串长度处理容易踩的坑";
$short = mb_strlen($title, 'UTF-8') > 15
? mb_substr($title, 0, 15, 'UTF-8') . '…'
: $title;
- 切勿混用:
substr($str, 0, 15)+mb_strlen($str, 'UTF-8')会导致截断位置错位 - 注意第三个参数是“字符数”,不是字节数;第四个编码参数不可省略
- 如果字符串含 HTML 标签,先 strip_tags() 再计算,否则
会被算作 3 个字符
判断空字符串别只用 strlen() == 0
strlen("") === 0 成立,但 strlen(" ")(全角空格)或 strlen("\t\n\r\0") 也返回非零值,而语义上它们常被视为“空”。真正健壮的判空应结合 trim 和 mb_strlen。
- 推荐写法:
mb_strlen(trim($str), 'UTF-8') === 0 - 若需兼容 null / false / array,先用
is_string($str)做类型检查,避免警告 - 注意
trim()默认只处理 ASCII 空白符,全角空格、不间断空格( )需手动指定:trim($str, "\x{3000}\x{00A0}")
mb_strlen() 就不能省;而 strlen() 只适合明确知道数据是纯 ASCII 或需要字节级精度的场景。编码参数写错、扩展未启用、混用 substr/mb_substr —— 这三类问题在线上环境最容易引发不可见的乱码或越界截断。











