intval() 从字符串左侧读取数字字符,遇非数字停止,非四舍五入或向下取整;仅识别ascii数字、±号及开头空格,不支持unicode数字、科学计数法;base=0仅识别0x/0b/0前缀,否则默认十进制;验证用户输入应优先用filter_var()而非intval()。

intval() 转换结果不符合预期?先看它到底怎么截断
intval() 不是四舍五入,也不是向下取整,它是从字符串**左侧开始读数字字符,遇到非数字就停**,然后转成整数。比如 intval("123abc") 得 123,intval("abc123") 得 0。
常见错误现象:intval("0.99") 返回 0(不是 1),intval(" 42") 返回 42(空格会被跳过),但 intval("42px") 也是 42——这在处理 CSS 值或用户输入时容易埋坑。
- 只认 ASCII 数字、
+、-和开头的空格;Unicode 数字(如全角“1”)一律返回0 - 不支持科学计数法:
intval("1e5")→1,不是100000 - 如果字符串以
0x开头且指定了base=0或base=16,才会按十六进制解析
base 参数到底什么时候起作用?别乱设 0
base 控制进制解析逻辑,但默认值 0 并不“自动推断所有格式”,它只识别三种前缀:0x(十六进制)、0b(二进制)、0 开头(八进制)。其他情况一律按十进制。
典型陷阱:intval("08", 0) 返回 0(因为 08 不是合法八进制,解析失败后 fallback 到 0);而 intval("08", 10) 才是 8。
立即学习“PHP免费学习笔记(深入)”;
- 明确要十进制时,直接写
intval($str, 10),别依赖0 -
base=16会强制按十六进制,intval("FF", 16)→255;但intval("FF", 0)→0(没0x前缀) - 传错
base值(如base=8解析"78")会中途截断,返回7
比 intval() 更安全的替代方案有哪些?
当你要确保“完整字符串必须是合法整数”,intval() 就不合适了——它太宽容。这时候该用 filter_var() 或正则 + 类型判断。
例如验证用户传来的 ID:filter_var($id, FILTER_VALIDATE_INT) 返回 false(不是 0)表示非法;而 intval("foo") 也返回 0,和真实值 0 混淆。
-
filter_var($str, FILTER_VALIDATE_INT, ["options" => ["min_range" => 1]])可同时校验范围 - 需要严格匹配整个字符串?用
ctype_digit(ltrim($str, "-+"))配合is_numeric()判断符号 - PHP 8+ 可考虑
is_int($val) || (is_string($val) && preg_match('/^[+-]?\d+$/', $val))
性能差异大吗?线上别为这点开销妥协安全性
intval() 是 C 实现的,确实比 filter_var() 快 2–3 倍,但这个差距只在百万级循环里才可测。真实 Web 请求中,I/O 和数据库耗时远高于类型转换。
真正影响性能的是误用:比如在循环里对同一字符串反复调用 intval() 却没缓存结果,或者用它做数据清洗主逻辑(导致后续还要额外校验)。
- 单纯转换且确定输入干净(如配置项硬编码),
intval()完全 OK - 处理用户输入、API 参数、表单值,优先用
filter_var()或显式正则,避免“转出 0 却以为成功”的逻辑漏洞 -
intval(null)返回0,intval([])也返回0——这种隐式转换最容易漏掉空值/数组误传
最常被忽略的点:很多人以为 intval() 是“安全转换函数”,其实它根本不管输入是否合理,只管尽可能捞出一个整数。信它,就得自己兜底验证语义。











