php如何计算中文字符长度 php获取中文长度【指南】

6次阅读

php如何计算中文字符长度 php获取中文长度【指南】

mb_strlen() 而不是 strlen()

php 默认的 strlen() 按字节计数,一个 UTF-8 中文字符占 3 字节,结果就是“你好”返回 6,完全不能反映真实字符数。mb_strlen() 才是专为多字节编码设计的函数,它能正确识别中文、日文、emoji 等 Unicode 字符。

必须显式指定编码,否则依赖默认内部编码(可能不是 UTF-8):
mb_strlen($str, 'UTF-8')

  • 不传第二个参数时,行为不可靠——尤其在 mb_internal_encoding() 被改过或未设的情况下
  • 如果字符串实际是 GBK 编码(比如老系统),却硬写 'UTF-8',结果会错乱甚至截断
  • 常见错误现象:mb_strlen("你好", 'UTF-8') 返回 2 ✅;但 mb_strlen("你好", 'GBK') 返回 4 ❌(GBK 下每个中文占 2 字节,但它仍按字符逻辑算,所以其实也返回 2 ——重点是:别混用编码!)

注意 mb_strlen() 的扩展依赖和配置

这个函数属于 mbstring 扩展,不是 PHP 默认始终开启的。线上环境常有没装或被禁用的情况,直接调用会报 Fatal Error: Uncaught Error: Call to undefined function mb_strlen()

  • 检查是否启用:extension_loaded('mbstring') 或运行 php -m | grep mbstring
  • 没启用时,apache 下需确认 php.iniextension=mbstring 未被注释;CLI 环境可能用的是另一份 php.ini,得单独查
  • 某些 docker 镜像(如 php:alpine)默认不带 mbstring,要手动 apk add php82-mbstring 类似操作

替代方案:没有 mbstring 时怎么安全 fallback

真遇到无法启用扩展的受限环境(比如某些共享主机),可用 iconv_strlen() 替代,它也支持多字节,且更轻量:

立即学习PHP免费学习笔记(深入)”;

iconv_strlen($str, 'UTF-8')

  • 它不依赖 mbstring,只要 iconv 扩展存在(PHP 几乎都自带)
  • 但要注意:当字符串含非法 UTF-8 序列时,iconv_strlen() 可能返回 false,而 mb_strlen() 会尽力解析并返回近似值
  • 别用正则 preg_match_all('/./u', $str) ——性能差,且对某些组合字符(如带变音符号的汉字、ZWJ 连接 emoji)统计不准

中文长度计算的实际陷阱:全角/半角、空格、不可见字符

“中文字符长度”在业务中往往不只是技术问题。比如用户昵称限制 10 个字符,但“abc”(全角 ASCII)和“abc”(半角)视觉一样长,mb_strlen() 都算作 3;而“ ”(中文空格)、“ ”(全角空格)、零宽空格 u200b 全都会被计入。

  • 前端输入没过滤时,用户可能粘贴带格式文本,导致看似只有 5 个字,实际长度超限
  • 建议入库前用 mb_ereg_replace('[[:space:]]+', ' ', $str) 清理多余空白,或用 trim() + mb_convert_kana() 统一全半角(后者需 mbstring
  • emoji 表情如 ??、?‍? 在 UTF-8 下占多个码点,mb_strlen() 默认按 Unicode 码点计,通常没问题;但若需按“视觉字形”计数(比如排版),就得上 grapheme_* 函数了——那又是另一层复杂度

真正麻烦的从来不是“怎么算”,而是“算什么”——业务定义模糊时,mb_strlen() 给出的数字只是起点,不是答案。

text=ZqhQzanResources