strlen()按字节计算字符串长度,ASCII字符(数字、字母、符号)各占1字节,中文等UTF-8多字节字符则返回字节数而非字符数;需用mb_strlen()获取真实字符数。

PHP 中 strlen() 计算数字字符和字母一样,按字节算
strlen() 不区分字符类型,它只数字符串占用的字节数。数字(如 "123")、英文字母、符号(如 "@#")在 ASCII 范围内都占 1 字节,所以 strlen("123") 返回 3,strlen("abc123") 返回 6。
常见误解是以为“数字不算字符”或“数字长度特殊处理”,其实完全不需要——只要字符串编码是 UTF-8 且内容全是 ASCII 字符(0–127),strlen() 就准确反映“可见字符个数”。
- 中文、日文、emoji 等非 ASCII 字符在 UTF-8 下占多字节(如中文通常占 3 字节),
strlen()会返回字节数而非“字符数”,这时不能用它判断“有几个汉字” - 如果字符串可能含中文,改用
mb_strlen($str, 'UTF-8') - 空格、制表符
"\t"、换行符"\n"都算 1 字节,会被计入长度
判断字符串是否“只含数字”不能只靠长度
长度只是基础信息,判断“是否为纯数字”得用逻辑校验,不是看 strlen() 返回值。比如 "000" 长度是 3,但它是合法数字;"12a" 长度也是 3,却不是纯数字。
- 推荐用
ctype_digit($str):要求非空、全由 ASCII 数字组成、不能有前导空格或符号 - 想允许负号或小数点?用正则:
preg_match('/^-?\d+(\.\d+)?$/', $str) -
is_numeric($str)范围太宽,会把"1e4"、" 123 "也判为 true,慎用于表单校验
UTF-8 中文混排时,strlen() 和 mb_strlen() 结果不同
例如 $str = "abc你好123";:
立即学习“PHP免费学习笔记(深入)”;
strlen($str) // 返回 12(a/b/c 各 1 字节,"你好"各 3 字节,1/2/3 各 1 字节 → 3 + 6 + 3 = 12) mb_strlen($str, 'UTF-8') // 返回 9(3 英文 + 2 中文 + 3 数字 = 9 个字符)
如果你要限制用户输入“最多 10 个字符”,应该用 mb_strlen();如果要做底层协议拼包或计算内存占用,才用 strlen()。
- 不指定
mb_strlen()的第二个参数,可能因默认编码非 UTF-8 导致结果异常 - PHP 8.0+ 可设默认内部编码:
mb_internal_encoding('UTF-8');,之后mb_strlen($str)可省略第二个参数 - 数据库字段长度限制(如
VARCHAR(255))通常按字符数计,对应mb_strlen(),不是strlen()
实际校验场景:用户名/密码长度 + 字符类型组合判断
比如要求“6–20 位,必须含数字和字母”:
- 先用
mb_strlen($str, 'UTF-8')判断总长度,避免中文被误判超长 - 再分别检查:
preg_match('/[a-zA-Z]/', $str)和preg_match('/\d/', $str) - 注意不要用
strlen()替代mb_strlen()做长度拦截,否则用户输两个汉字就卡在“长度不足6” -
前端 JS 的
.length对中文也是按 Unicode 字符计(类似mb_strlen),前后端校验逻辑要对齐
真正容易出错的不是“数字算不算长度”,而是混用 strlen() 和 mb_strlen()、忽略编码上下文、以及把“长度校验”和“字符类型校验”当成一回事。











