应根据语义需求选择函数:字符数用mb_strlen($str, 'UTF-8'),字节数用strlen();避免隐式编码依赖,统一UTF-8环境,截取须配对使用mb_substr()。

PHP 7.1 中要更准确地计算字符串长度,关键不是“选更快的函数”,而是“选对语义的函数”——明确你要的是字节数、字符数,还是用户感知的可编辑单元数。
按字符数统计(最常用):用 mb_strlen() 显式指定 UTF-8
这是处理中文、emoji、日文等多字节文本的标准做法。不指定编码或依赖默认设置容易出错。
- ✅ 正确写法:
mb_strlen($str, 'UTF-8')—— 返回真实字符个数,如 "你好" 得 2,"??"(ZWJ 组合 emoji)也得 1 - ❌ 错误写法:
mb_strlen($str)或mb_strlen($str, 'utf8')(大小写敏感,部分环境可能失败) - ⚠️ 注意:确保
mbstring扩展已启用,且字符串实际编码确实是 UTF-8;若混入 GBK 数据,需先转换或检测
按字节数统计(特定场景):用 strlen()
当你需要与数据库 VARBINARY 字段、网络协议包、文件存储空间对齐时,字节数才是关键。
- ✅ 适用场景:校验上传文件名长度限制(某些旧系统按字节截断)、计算缓存 key 长度、配合
substr()做底层字节操作 - ❌ 不适合表单验证、前端显示计数、MySQL
VARCHAR(50)字符限制等——这些都以“字符”为单位 - ? 小技巧:UTF-8 下,
strlen()结果 ≥mb_strlen($str, 'UTF-8'),差值大致反映多字节字符数量
避免踩坑的硬性建议
很多长度异常其实源于环境或调用方式问题,而非函数本身。
立即学习“PHP免费学习笔记(深入)”;
- 统一项目字符集为 UTF-8(PHP 文件保存、HTTP header、数据库连接、HTML meta 全部一致)
- 禁用
mb_internal_encoding()的隐式依赖,所有mb_*函数都显式传编码参数 - 用户输入进来的字符串,不盲目信任
mb_detect_encoding()—— 它只是启发式猜测,优先靠协议约定(如 API 文档声明 UTF-8) - 截取字符串必须配对使用:
mb_substr($str, 0, 10, 'UTF-8'),不能混用substr(),否则会切碎中文导致乱码
什么情况下才考虑 IntlBreakIterator?
它不是用来算“长度”的,而是解决“怎么断词、怎么选中、怎么换行才符合语言习惯”。比如:
- 双击选中“苹果手机”作为一个词,而不是分开成“苹果”和“手机”
- 在含 emoji 表情的昵称中,让光标能正确停在 ?? 而不是卡在中间字节
- 给长文本做语义级自动断行(非简单按字符数硬截)
如果你的需求只是“这个字符串有多少个字”,那它属于过度设计——工具错配,反而增加维护成本和兼容风险。



















