需先检查 php_int_size === 8,再用 filter_var($val, filter_validate_int, ['options' => ['min_range' => php_int_min, 'max_range' => php_int_max]]) !== false。

PHP 怎么判断一个值是不是 int 且能安全存下 64 位整数?
PHP 的 is_int() 只管类型,不管数值范围。在 32 位系统上,PHP_INT_MAX 是 2147483647,超过它就不是“真正的 int”——哪怕你用 (int) 强转,也会溢出变负或截断。所以光靠 is_int() 完全不可靠。
- 先确认运行环境:
PHP_INT_SIZE === 8才表示当前是 64 位整型支持环境(Linux x64 / macOS / 64 位 Windows PHP) - 再检查值本身:
is_int($val) && $val >= PHP_INT_MIN && $val - 注意:字符串形式的 "9223372036854775807" 不会被
is_int()认出来,得先filter_var($str, FILTER_VALIDATE_INT)或ctype_digit()+ 范围比对
为什么 (int)"9223372036854775807" 在某些机器上会变成 -1?
这是强制类型转换触发的底层溢出行为。PHP 把字符串转成整数时,会按当前平台的整型宽度截断:32 位系统最大只认到 2147483647,超出部分直接回绕。即使你 echo 出来像“正常”,实际内存里已经是错的。
- 典型错误现象:
var_dump((int)"9223372036854775807");输出int(-1)(32 位环境) - 正确做法:用
filter_var($str, FILTER_VALIDATE_INT, ['options' => ['min_range' => PHP_INT_MIN, 'max_range' => PHP_INT_MAX]]) !== false - 性能影响:
filter_var比is_int慢一点,但换来的是确定性;线上服务别图快跳过范围校验
JSON 解析大整数时自动转成浮点,怎么保住精度?
PHP 默认用 json_decode() 解析 JSON,遇到超 PHP_INT_MAX 的数字(比如 MongoDB ObjectId 或雪花 ID),会悄悄变成 float,精度丢失不可逆——这是最隐蔽也最常被忽略的问题。
- 必须加参数:
json_decode($json, flags: JSON_BIGINT_AS_STRING),这样大数会变成string类型 - 之后再用上面说的
filter_var(... FILTER_VALIDATE_INT ...)做二次校验 - 兼容性注意:PHP 5.4+ 支持
JSON_BIGINT_AS_STRING,旧版本只能靠正则预处理或换jsonc扩展 - 别信
is_numeric()——它对 "1e100" 也返回 true,根本不是整数
用 gmp_init() 或 bcmul() 能不能绕过限制?
可以,但没必要为“判断”这种事引入 GMP/BCMath。它们解决的是「计算」问题,不是「识别」问题。GMP 对象本身不是 int,is_int(gmp_init('123')) 永远是 false。
立即学习“PHP免费学习笔记(深入)”;
-
gmp_init()适合做超大整数运算,不适合做类型判断 - 如果你只是想确认一个输入“是否合法 64 位有符号整数”,坚持用
filter_var+PHP_INT_MIN/MAX最轻量、最直观 - 容易踩的坑:有人把字符串传给
gmp_cmp($a, $b)就以为“比了大小”,其实没校验它是不是真整数格式,空格、前导 +、科学计数法都可能混进去
真正麻烦的从来不是“怎么写判断逻辑”,而是忘记检查 PHP_INT_SIZE、忘记 JSON 默认丢精度、以及把字符串当 int 直接参与算术运算——这些地方一错,后面全崩。











