最可靠方法是strlen((String)abs($n)),可正确处理负数、0及边界情况;超大数字字符串则直接strlen($str),避免整型转换失效。

用 strlen((string)$n) 最直接,但要注意负数
php 里判断整型有多少位数字,最常用也最不容易出错的方式就是转成字符串再算长度。比如 $n = 1234,strlen((string)$n) 返回 4。
但负数会多一个负号:如果 $n = -123,strlen((string)$n) 是 4,而你真正想数的是“数字位数”,应该只算 3。
- 对有符号整数,统一先取绝对值:
strlen((string)abs($n)) - 注意
0的情况:abs(0)还是0,strlen("0")正确返回1,不用额外处理 - 避免直接
strlen($n)—— PHP 7+ 会警告,因为strlen期望字符串,传整数属于隐式转换,不安全
log10() 能算但容易翻车,慎用
数学上,正整数 n 的位数是 floor(log10($n)) + 1。比如 log10(1000) == 3,加 1 得 4。
问题在于边界和类型:
立即学习“PHP免费学习笔记(深入)”;
-
log10(0)会触发警告(Warning: log10(): Invalid Floating point operation),必须提前判断$n === 0 -
log10(-123)直接报错(负数无实数对数),得先abs() - 浮点精度问题:比如
log10(999)理论是2.99956...,floor后是2,加 1 得3没问题;但某些大整数(如接近PHP_INT_MAX)转成 float 可能丢失精度,导致log10结果偏差 - 性能上比字符串法略快,但实际差异微乎其微,不值得为这点速度引入风险
用循环除法?没必要,纯属炫技
有人写个 while 循环不断 $n = (int)($n / 10) 计数,逻辑没错,但完全没必要。
- 代码更长、可读性差,还容易漏掉
0或负数的处理 - 整数除法在 PHP 中受
intdiv和普通除法混用影响,PHP 7+ 除法默认返回 float,要强制(int)截断,反而增加出错点 - 没有明显性能优势,现代 CPU 对字符串长度计算早优化得飞起
注意大整数和字符串整数的陷阱
如果你拿到的是字符串形式的大数(比如 "12345678901234567890"),它可能已经超出 PHP_INT_MAX,无法安全转为整型再处理。
- 这种情况下,
strlen($str)是唯一靠谱方式 —— 它不关心内容是不是合法数字,只数字符 - 如果还要校验是否纯数字,加一层
ctype_digit(ltrim($str, '-')),但注意ctype_digit不接受负号,所以得先剔掉 - 别用
is_numeric()判断,它会把"1e5"、"0x1F"都当数字,但这些显然不是“十进制整数位数”的范畴
事情说清了就结束。真正容易被忽略的,是负数和超大字符串数——前者让 strlen 多算一位,后者让任何基于整型的方案直接失效。