
php强制转换int失败的典型表现
直接用 (int) 或 intval() 转一个带单位、空格或中文的字符串,比如 "123px"、" 456 "、"789元",结果往往是 0 或意外截断(如 "123px" 变成 123,但 "abc123" 变成 0)。这不是 bug,是 PHP 的类型转换规则在起作用:它从开头找数字,遇到非数字字符就停,开头没数字就返回 0。
用 filter_var() 做安全过滤再转整型
当输入不可控(比如表单、URL 参数、JSON 字段),靠 (int) 硬转容易埋雷。更稳妥的方式是先校验是否“看起来像整数”,再转:
-
filter_var($str, FILTER_VALIDATE_INT)会严格检查整个字符串是否为合法整数(支持+/-符号,不接受小数点、空格、单位等) - 如果验证失败,返回
false,不是0,能和“值就是 0”明确区分开 - 可配合
filter_var($str, FILTER_SANITIZE_NUMBER_INT)提前清理(但注意:它会删掉所有非数字字符,包括负号和加号,慎用)
示例:
var_dump(filter_var("123", FILTER_VALIDATE_INT)); // int(123)
var_dump(filter_var("123px", FILTER_VALIDATE_INT)); // bool(false)
var_dump(filter_var("-456", FILTER_VALIDATE_INT)); // int(-456)
var_dump(filter_var(" 789 ", FILTER_VALIDATE_INT)); // bool(false) ← 注意:前后空格也不行
需要容忍空格或单位?自己写白名单清洗逻辑
如果业务上必须接受 " 456px " 这类输入,又不能简单删光非数字(否则 "-123" 会变 123),就得手动处理:
立即学习“PHP免费学习笔记(深入)”;
- 先用
trim()去首尾空格 - 检查开头是否为
+或-,保留符号 - 用正则
/^[+-]?\d+$/匹配纯整数格式,或用preg_replace('/[^-\d]/', '', $str)粗暴清理(仅限你确认符号一定在最前) - 清理后务必再用
filter_var(... FILTER_VALIDATE_INT)校验,避免"--123"或"+-456"这种非法组合漏过
别依赖 intval("123px") 返回 123 —— 这行为在 PHP 8.1+ 对某些 Unicode 字符已开始报 E_DEPRECATED,未来可能收紧。
注意 settype() 和 intval() 的参数陷阱
settype($var, 'int') 和 intval($var) 表现几乎一致,都走 PHP 默认转换逻辑,所以同样会把 "abc123" 变成 0,"123abc" 变成 123。区别只在:intval() 支持第二个参数指定进制(如 intval("1010", 2) 得 10),而 settype() 不支持。
- 别传数组或对象给它们——
intval([])返回0,但这是无意义的转换,应提前判断类型 -
intval(null)返回0,intval("")也返回0,这两个值语义完全不同,不能靠返回值反推原始输入 - PHP 8.0+ 开始,对无效字符串转整型的静默处理越来越倾向抛出警告,线上环境建议开
E_WARNING并监控
真正难的不是怎么转,是怎么定义“这个字符串到底算不算一个有效整数”。边界案例(空、空格、符号混用、科学计数法字符串如 "1e3")永远比文档里写的多。留个日志,把原始输入和转换结果一起记下来,比补救强得多。











