最安全的写法是先用 filter_var($str, filter_validate_int) 验证,再转换;(int) 和 intval() 会静默截断或归零,无法保证数据合法性。

PHP字符串转整型最安全的写法是 (int) 和 intval()
直接强制类型转换 (int) 是最快、最直观的方式,适合已知字符串结构简单(如纯数字或带符号数字)的场景;intval() 更灵活,能指定进制、处理前导空格和非数字字符截断,但要注意默认只取开头有效数字部分。
-
(int) "123"→123;(int) "123abc"→123;(int) "abc123"→0 -
intval("123")→123;intval("0xFF", 16)→255;intval(" 42px")→42 - 两者对空字符串
""、" "、null都返回0,不是报错,这点容易误判为“转换成功”
用 filter_var() 验证并转整型才真正防错
如果字符串来源不可信(比如用户输入、API返回),光靠 (int) 或 intval() 会静默截断或归零,掩盖数据异常。这时候必须先验证格式是否合法整数,再转换。
-
filter_var("123", FILTER_VALIDATE_INT)→123(成功) -
filter_var("12.3", FILTER_VALIDATE_INT)→false(失败,不静默转成12) -
filter_var("-42", FILTER_VALIDATE_INT)→-42;filter_var("12345678901234567890", FILTER_VALIDATE_INT)→false(超 PHP 整型范围也判失败) - 配合
FILTER_FLAG_ALLOW_THOUSAND可支持带逗号的数字,但注意区域习惯差异,慎用
settype() 和 is_numeric() 不该混进转换流程
settype($var, 'int') 会修改原变量,且行为和 (int) 一致——静默截断,不适合做校验;is_numeric() 判定范围太宽,"1e4"、"0x1F"、" -12 " 都返回 true,但它不保证能安全转成整型,也不能替代 filter_var(..., FILTER_VALIDATE_INT)。
-
is_numeric("1e4") === true,但(int)"1e4"→1(科学计数法被当字符串首字符处理) -
is_numeric("0x1F") === true,但(int)"0x1F"→0(十六进制前缀不识别) -
settype($str, 'int')后$str变成整型,但原始非法内容已丢失,无法追溯问题源头
注意浮点字符串和大数字的陷阱
PHP 对浮点格式字符串(如 "123.45")转整型时不会四舍五入,而是直接截断小数部分;超大数字(如超过 PHP_INT_MAX 的字符串)用 (int) 会溢出变成边界值,而非报错或 null。
立即学习“PHP免费学习笔记(深入)”;
-
(int)"123.99"→123,不是124 -
(int)"9223372036854775808"(比PHP_INT_MAX大 1)→ 在 64 位系统上结果是PHP_INT_MIN(即负数),具体值依赖平台 - 需要精确大整数运算?别转
int,改用gmp_init()或bcadd()等扩展,或者保持字符串处理
真正麻烦的不是怎么转,而是没想清楚“这个字符串到底有没有资格被当成整数”。静默转换掩盖了脏数据,而验证逻辑一旦漏掉边界情况(比如负号位置、空格、Unicode空格、\0 字符),后面就全是隐性 bug。











