strlen()返回字节数而非字符数,UTF-8下中文占3字节,故"你好"返回6;应使用mb_strlen($str, 'UTF-8')计算真实字符数,且需确保编码参数与字符串实际编码一致。

strlen() 计算中文返回的是字节数,不是字符数
因为 strlen() 完全不关心字符编码,它只数字符串在内存里占了多少个字节。UTF-8 下一个中文字符占 3 个字节(极少数生僻字占 4 字节),所以 "你好" 用 strlen() 返回 6,而不是你预期的 2。
这会导致表单验证误判、前端显示截断、数据库字段超长报错等实际问题——你限制“最多 10 个字符”,用户输 4 个汉字就触发了限制,因为 strlen() 算出来是 12。
mb_strlen() 才是正确计算中文字符数的函数
mb_strlen() 是专为多字节编码设计的,它会按指定编码规则解析字节流,把连续的 3 个字节识别成“一个 UTF-8 中文字符”。必须传入编码参数,否则行为不可靠:
- ✅ 正确:
mb_strlen($str, 'UTF-8') - ⚠️ 危险:
mb_strlen($str)—— 依赖mb_internal_encoding()的当前值,跨环境容易出错 - ❌ 错误:
mb_strlen($str, 'GBK')—— 如果字符串实际是 UTF-8 编码,结果完全不可信
常见踩坑点:编码不匹配比函数选错更致命
即使用了 mb_strlen(),如果第二个参数和字符串真实编码不一致,结果照样错。比如:
立即学习“PHP免费学习笔记(深入)”;
- 从 MySQL 读出的字段是
utf8mb4编码,却传'UTF-8'—— 大部分情况能兼容,但遇到 emoji 或扩展汉字可能出错 - 用户 POST 过来的数据是 GBK 编码(老系统或特定终端),却硬写
'UTF-8'——mb_strlen()会把两个 GBK 字节当成一个乱码字符,长度直接少一半 - 没开
mbstring扩展,调用mb_strlen()直接报Fatal error: Uncaught Error: Call to undefined function mb_strlen()
中英文混合字符串也得统一用 mb_* 系列
别以为“纯英文就安全”——只要字符串里可能出现中文(比如用户昵称、评论、地址),就必须全程使用 mb_strlen()、mb_substr()、mb_strpos() 等函数。混用 substr() 截取中英文混合串,大概率在中文中间切断,产生乱码或空字符。
真正麻烦的不是“要不要用”,而是“怎么确保所有地方都用对了”。最稳妥的做法是在项目入口(如 index.php 或框架启动文件)第一行加上:
mb_internal_encoding('UTF-8');然后所有 mb_*() 调用都可以省略编码参数——但前提是,你 100% 确认整个请求链路(HTTP 请求头、数据库连接、文件读取)都是 UTF-8,否则这个“省略”反而埋下隐患。



















