应使用 filter_var() 验证转换,而非 (int) 强转;因后者对非法输入静默转 0 或截断,易引发安全与逻辑错误,而 filter_var() 可明确区分合法/非法输入并支持范围校验。

直接用 (int) 强转可能丢数据,别无脑 cast
PHP 中 $_GET 里的值永远是字符串,哪怕 URL 里写的是 ?id=123,$_GET['id'] 的类型也是 string。直接写 $id = (int)$_GET['id']; 看似简单,但遇到非法输入(比如 ?id=abc 或 ?id=123abc)会静默转成 0,容易掩盖逻辑错误或引发越权访问。
- 空字符串
''→(int)''得0 - 带前导空格的
' 42'→(int)会截断并转出42(PHP 8.1+ 已弃用此行为) -
'123abc'→(int)只取开头数字部分,得123,后缀被忽略 - 科学计数法如
'1e5'→(int)结果是1(不是100000)
用 filter_var() 验证并转换最稳妥
这是 PHP 官方推荐方式,兼顾类型校验和安全过滤。它能明确区分「合法整数」「非法输入」,且支持范围限制。
- 基本用法:
$id = filter_var($_GET['id'], FILTER_VALIDATE_INT);,合法返回 int,非法返回false - 加范围检查:
filter_var($_GET['id'], FILTER_VALIDATE_INT, ['options' => ['min_range' => 1, 'max_range' => 9999]]); - 注意:如果参数根本没传(
$_GET['id']不存在),filter_var会返回null,不是false,判断时建议用=== false或先isset() - 不建议用
FILTER_SANITIZE_NUMBER_INT替代验证——它会删掉所有非数字字符(如把'-123'变成'123'),破坏符号和语义
需要默认值时,别在强转后补逻辑
常见错误是先强转再判断是否为 0,然后设默认值——这会把真实传入的 ?id=0 也覆盖掉。
- 正确做法:先判断参数是否存在且非空,再验证转换:
$id = $_GET['id'] ?? null; if ($id !== null && $id !== '') { $id = filter_var($id, FILTER_VALIDATE_INT); if ($id === false) { // 处理非法输入,比如抛异常或返回 400 http_response_code(400); exit('Invalid id'); } } else { $id = 1; // 默认值 } - 更简洁的写法(适合简单场景):
$id = filter_var($_GET['id'] ?? '', FILTER_VALIDATE_INT) ?: 1;,但要注意:这里?:会把0当作 falsy,所以仅适用于默认值不为 0、且允许 0 被跳过的场景
intval() 和 filter_var() 到底选哪个
intval() 是兼容性更强的老函数,但行为不够严格;filter_var() 是现代 PHP 的标准验证接口,语义清晰、可配置、易测试。
立即学习“PHP免费学习笔记(深入)”;
-
intval('123abc', 10)返回123,和(int)类似,无法拒绝脏输入 -
filter_var('123abc', FILTER_VALIDATE_INT)明确返回false,强制你处理错误分支 - 如果项目要求 PHP intval() + 手动正则校验(如
preg_match('/^-?\d+$/', $str)) - 性能差异几乎可以忽略,别拿“
filter_var慢”当借口绕过验证
page= 应该报错,而缺失 page 参数才走默认值。验证逻辑必须覆盖这个边界。











