表单值永远是字符串,is_int()无法验证;应使用filter_var()配合filter_validate_int,支持范围限制、符号识别和严格模式,且需先用isset()兜底避免未提交字段触发notice。

用 is_int() 判定变量类型,但表单值永远不是整型
PHP 表单提交的所有数据,无论用户输的是 123 还是 0,到 PHP 端都是字符串(string)。所以直接用 is_int($_POST['age']) 永远返回 false——它只认真正的整型变量,不认“看着像整数”的字符串。
- 真正适合判断表单输入的函数是
filter_var()配合FILTER_VALIDATE_INT -
is_numeric()会把"123"、"-45"、甚至"1.23e4"都当真,不安全 -
ctype_digit()只能处理非负整数,且要求字符串不能带符号或空格,太脆弱
filter_var() 验证整数:支持范围、符号和严格模式
这是最稳妥的方案,既能判断是否为合法整数字符串,又能限制取值范围,还能区分 "123" 和 " 123 "。
- 基础用法:
filter_var($_POST['id'], FILTER_VALIDATE_INT) !== false - 允许负数?默认就支持,不用额外配置
- 限制范围?加
options参数:filter_var($_POST['level'], FILTER_VALIDATE_INT, ['options' => ['min_range' => 1, 'max_range' => 10]]) - 去首尾空格?它默认不 trim,所以
" 123 "会失败;如需容错,先trim()再验证
if (filter_var(trim($_POST['score']), FILTER_VALIDATE_INT) === false) {
echo '分数必须是整数';
}
为什么不用 (int) 强转再比较?
有人写 (int)$_POST['num'] == $_POST['num'] 来“反向验证”,这看似能过 "123",但会漏掉很多边界问题。
-
"123abc"强转后是123,比较结果为true,实际非法 -
"0123"(八进制写法)强转后是83,但用户本意可能是想输十进制123,语义已丢失 -
"12.3"强转为12,比较失败,但错误提示模糊,不如filter_var()明确返回false - 性能差异可忽略,但逻辑清晰度和可维护性差一截
注意 empty() 和 isset() 不解决类型问题
这两个函数常被误用作“非空整数”判断,但它们只管存在性和真假值,不管类型。
立即学习“PHP免费学习笔记(深入)”;
-
empty("0")是true,导致合法的零值被拒 -
isset($_POST['count'])只说明键存在,不保证值是数字 - 如果要同时检查“存在 + 非空 + 整数”,得组合判断:
isset($_POST['count']) && $_POST['count'] !== '' && filter_var($_POST['count'], FILTER_VALIDATE_INT) !== false
真正容易被忽略的是:表单字段可能根本没提交(比如 checkbox 未勾选时不会出现在 $_POST 中),这时 filter_var($_POST['flag'], FILTER_VALIDATE_INT) 会触发 Notice: Undefined index。务必先用 isset() 或 array_key_exists() 做存在性兜底。











