正确做法是先用(string)强转再测长度,负数需先abs();筛选3位数应使用strlen((string)abs($n))===3,而非直接strlen($n)。

用 strlen() 判断数字位数时要注意类型转换
PHP 中数字本身没有“位数”概念,strlen() 只能作用于字符串。直接对整数调用会触发隐式转换,但遇到科学计数法(如 1e10)或浮点数(如 123.0)时结果不可靠。
正确做法是先用 (string) 强转,再测长度。注意负数带负号,如 -42 的 strlen 是 3,若只需纯数字位数,得先 abs()。
筛选 3 位数的数组元素:常见写法与陷阱
假设数组是 $nums = [5, 99, 100, 999, 1000, -123],要取「绝对值为 3 位数」的项:
- 错误写法:
array_filter($nums, fn($n) => strlen($n) === 3)——99变成字符串是"99",长度为 2;-123是"-123",长度为 4 - 推荐写法:
array_filter($nums, fn($n) => strlen((string) abs($n)) === 3) - 更健壮写法(兼容浮点、字符串数字):
array_filter($nums, fn($n) => is_numeric($n) && ctype_digit(ltrim((string) $n, '-')) && strlen(ltrim((string) $n, '-')) === 3)
性能敏感场景下避免重复类型转换
如果数组很大或需多次筛选不同位数,反复 (string) + abs() + strlen() 会拖慢速度。可预处理成「数字 → 位数」映射:
$digitMap = array_map(fn($n) => is_numeric($n) ? strlen(ltrim((string) (int) $n, '-')) : 0, $nums); $threeDigitIndices = array_keys(array_filter($digitMap, fn($d) => $d === 3)); $result = array_intersect_key($nums, array_flip($threeDigitIndices));
这种写法把计算从 O(n×操作) 降为 O(n),适合批量位数判断。
立即学习“PHP免费学习笔记(深入)”;
用正则匹配位数容易忽略边界情况
有人倾向用 preg_match('/^\d{3}$/', $n),但该正则只匹配纯数字字符串,对整数或浮点数会失败;且无法处理带符号数。若坚持用正则,必须先格式化:
-
preg_match('/^\d{3}$/', ltrim((string) (int) $n, '-'))—— 仅适用于整数截断场景 - 不推荐对原始数组直接
preg_match,因为100.5、"100abc"等输入会让逻辑失控 - 正则更适合清洗后数据,而非原始混合类型数组的位数筛选
真正容易被忽略的是:位数筛选常和业务语义耦合,比如「3 位数」在身份证号里可能是前三位,在价格里可能代表百元级——别只盯 strlen,先确认数值范围是否比位数更可靠(例如 $n >= 100 && $n )。











