mb_strlen返回字符数而strlen返回字节数,因UTF-8中一个汉字占3字节但算1字符;未显式指定编码或编码不匹配会导致计算错误或乱码,故必须传'UTF-8'等明确编码参数。

mb_strlen 为什么返回的长度和 strlen 不一样
因为 mb_strlen 按字符数计,strlen 按字节数计。中文、emoji 或带重音符号的字母(如 é、ñ)在 UTF-8 下占多个字节,strlen 会把它们算成 2–4 个“单位”,而 mb_strlen 知道这是 1 个 Unicode 字符,返回 1。
常见错误现象:mb_strlen('好', 'UTF-8') 返回 1,strlen('好') 返回 3(UTF-8 编码下“好”是 3 字节)。如果用 strlen 做表单长度校验,用户输 10 个汉字就可能被截断或报错“超长”,实际只该算 10 个字符。
- 必须显式传入编码参数,比如
'UTF-8';不传时依赖mb_internal_encoding()当前值,容易出错 - PHP 8.0+ 默认内部编码是 UTF-8,但老项目或 CLI 环境可能仍是 ISO-8859-1,不指定编码会导致乱码字符长度计算错误
- 数据库字段定义(如
VARCHAR(255))按字符计,和mb_strlen对齐才合理
mb_strlen 的第三个参数 $encoding 怎么设才安全
不要依赖默认值。即使设置了 mb_internal_encoding('UTF-8'),某些 SAPI(如 Apache mod_php)或扩展(如 mbstring.func_overload)可能干扰行为。最稳妥的是每次调用都明确传参。
- 统一用
mb_strlen($str, 'UTF-8'),大小写敏感,'utf8'或'utf-8'都行,但推荐标准写法'UTF-8' - 如果字符串来源不可控(如 POST 数据、文件读取),先用
mb_detect_encoding($str, ['UTF-8', 'GB2312', 'BIG5'], true)判断,再传给mb_strlen,否则可能返回FALSE - 遇到
mb_strlen返回FALSE,大概率是编码不匹配或含非法字节,不是函数坏了
和 mb_substr 配合截取中文字符串时要注意什么
mb_strlen 和 mb_substr 必须用相同编码参数,否则位置错乱。比如用 mb_strlen($s, 'UTF-8') 得到长度 12,却用 mb_substr($s, 0, 10, 'GB2312') 截取,结果可能缺字或乱码。
- 截取前先确认源字符串编码:用
mb_check_encoding($str, 'UTF-8')返回true才放心操作 - 避免混用:不要用
substr+mb_strlen,substr是字节级的,对多字节字符会从中切断,产生乱码 - 性能提示:
mb_strlen比strlen慢,高频场景(如日志统计)可缓存结果,或改用iconv_strlen($str, 'UTF-8')(需 iconv 扩展,通常更快)
mb_strlen 在 JSON 或数据库写入前要不要用
要,但不是为了“防止超长”,而是为了提前暴露编码问题。MySQL utf8mb4 支持 4 字节 emoji,但 PHP 的 mb_strlen 在 'UTF-8' 下能正确识别它为 1 个字符;而旧版 MySQL 的 utf8 只支持 3 字节,此时 mb_strlen 虽然算对了,但插入会失败——所以长度检查只是第一步。
- 入库前用
mb_strlen($input, 'UTF-8') > 255判断是否超字段限制,比事后捕获 SQL 错误更可控 - JSON 输出时,
json_encode默认处理 UTF-8 字符串没问题,但若输入是 GBK 编码,mb_strlen会误判长度,且json_encode可能返回false - 注意:
mb_strlen(null)返回0,mb_strlen([])触发 warning,空值务必先判断
真正容易被忽略的是:不同环境的 mbstring 扩展配置可能禁用部分函数,上线前用 function_exists('mb_strlen') 检查,别只在本地开发机上测通就以为万事大吉。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











