最可靠方法是array_filter()配合is_numeric(),但需注意其会误判十六进制、八进制;严格十进制校验应使用filter_var($str, FILTER_VALIDATE_FLOAT);ctype_digit()仅适用于无符号纯数字字符串,不推荐通用场景。

用 array_filter() 配合 is_numeric() 最可靠
直接遍历判断最直观,但容易漏掉科学计数法(如 "1e3")或带符号字符串(如 "-42")。is_numeric() 能覆盖这些情况,而 array_filter() 默认保留“真值”,所以反过来用 !is_numeric() 找出非数字项更稳妥:
function is_all_numeric($arr) {
if (!is_array($arr)) return false;
$non_numeric = array_filter($arr, function($v) {
return !is_numeric($v);
});
return empty($non_numeric);
}
注意:is_numeric() 会把 "0x1A"(十六进制字符串)、"0123"(八进制写法)也判为 true,如果业务要求严格十进制整数/浮点数,不能靠它。
要严格十进制数字?用 filter_var() + FILTER_VALIDATE_FLOAT
当必须排除十六进制、八进制、科学计数法,只接受纯十进制数字(包括小数和负数)时,filter_var() 更可控:
function is_all_decimal($arr) {
if (!is_array($arr)) return false;
foreach ($arr as $v) {
// 先转字符串,避免 null/true/false 被误判
$str = (string)$v;
// 空字符串、"inf"、"-inf"、"nan" 都不通过
if (filter_var($str, FILTER_VALIDATE_FLOAT) === false) {
return false;
}
}
return true;
}
-
FILTER_VALIDATE_FLOAT对"1e2"返回false,符合严格场景 - 注意它允许开头空格(如
" 123"),如需禁止,先用trim() - 对整数(如
42)也返回 true,无需额外处理
别用 ctype_digit() 直接判断数组元素
ctype_digit() 看似简单,但它只认纯数字字符串(如 "123"),且不接受负号、小数点、空格,也不接受整数类型变量。传入 -5 或 3.14 或 "-7" 全部返回 false,极易误判:
立即学习“PHP免费学习笔记(深入)”;
// ❌ 错误示例
$test = [123, "456", "-789"];
var_dump(array_map('ctype_digit', $test));
// 输出: [false, true, false] —— 但 -789 明显是数字
除非你确定数组里全是不含符号的非负整数字符串,否则别碰 ctype_digit()。
性能敏感时注意 is_numeric() 的隐式类型转换开销
is_numeric() 内部会尝试多种解析路径,比纯字符串检查慢。如果数组很大(比如上万项)且已知数据格式干净(例如全来自 json_decode() 的数字),可先用 is_int() / is_float() 快速分流:
function is_all_numeric_fast($arr) {
foreach ($arr as $v) {
if (is_int($v) || is_float($v)) continue;
if (is_string($v) && is_numeric($v)) continue;
return false;
}
return true;
}
这能跳过对整数/浮点数类型的冗余字符串解析,实测在大数据量下快 2–3 倍。但前提是你的数据确实以原生数字类型存在——从表单或 JSON 来的永远是字符串,这点容易被忽略。



















