php整型最小值无固定常量,32位为-2147483648、64位为-9223372036854775808;推荐用-(php_int_max + 1)兼容php 5.6+,php 8.3的php_int_min为实验性功能,默认不可用。

PHP整型最小值取决于平台和编译选项,不是固定常量
PHP没有内置的 PHP_INT_MIN 常量(直到 PHP 8.3 才加入实验性支持),所以不能像 C 那样直接引用标准宏。它的最小值由底层 C 编译器决定:32 位系统通常是 -2147483648,64 位系统通常是 -9223372036854775808。但要注意,这还受 PHP 编译时是否启用 –enable-largefile 或使用 long long 影响。
实际开发中别硬记数字,用计算方式更可靠:
-
-(PHP_INT_MAX + 1)是最通用、兼容 PHP 5.6+ 的写法,适用于所有支持整型溢出检测的环境 - 不要用
~PHP_INT_MAX,在某些 Zend VM 模式下可能因符号扩展异常导致结果错误 - 如果运行在 HHVM 或极老的 PHP 5.2 之前版本,
PHP_INT_MAX可能未定义,需先判断:defined('PHP_INT_MAX') ? -(PHP_INT_MAX + 1) : -2147483648
PHP 8.3+ 可直接用 PHP_INT_MIN,但默认不启用
PHP 8.3 引入了 PHP_INT_MIN,但它被标记为“实验性”,必须在编译时显式开启 --enable-zts 或配置 zend.assertions=1 才可用。线上环境几乎不会开这个开关,所以生产代码里仍不建议依赖它。
- 检查是否可用:
var_dump(defined('PHP_INT_MIN'));—— 大部分服务器返回false - 即使
PHP_INT_MIN存在,其值也等价于-(PHP_INT_MAX + 1),无额外精度或范围提升 - 不要在 composer.json 的
require中写"php": "^8.3"就默认能用,得确认部署环境真实启用了该特性
用 filter_var() 或 is_int() 判断时,负数边界容易误判
PHP 的整型范围是“有符号”的,但很多类型校验函数不检查数值是否落在 PHP_INT_MIN~PHP_INT_MAX 内,只看是否能无损转成整型。比如字符串 "-9223372036854775809" 在 64 位系统上会静默转成 -9223372036854775808(即溢出回绕),is_int() 仍返回 true。
立即学习“PHP免费学习笔记(深入)”;
- 安全校验整数范围,必须手动比对:
$n >= PHP_INT_MIN && $n -
filter_var($str, FILTER_VALIDATE_INT, ['options' => ['min_range' => PHP_INT_MIN, 'max_range' => PHP_INT_MAX]])才真正有效 - 从 JSON 解析来的数字(如
json_decode('{"n":-9223372036854775809}', true))在溢出时会自动转为 float,此时is_int()返回false,但值已失真
数据库字段映射到 PHP 整型时,tinyint/smallint 容易越界
MySQL 的 TINYINT SIGNED 范围是 -128~127,而 PHP 整型最小值远小于此。看似安全,但 ORM(如 Laravel Eloquent)或 PDO 默认把所有整数列都映射为 PHP int,一旦数据库存了超出 PHP 当前平台整型范围的值(比如从其他语言写入的超大负数),PHP 会强制截断或转 float,后续运算就不可靠。
- 读取前加类型断言:
(int)$row['value'] === $row['value']只能判断是否“看起来像整数”,不防溢出 - 更稳妥的是用
gmp_init()或bcadd()处理可能超界的整数,尤其金融类场景 - PDO 预处理绑定参数时,
PDO::PARAM_INT不校验范围,传入-9223372036854775809会被悄悄变成-9223372036854775808
整型边界的麻烦不在“怎么算”,而在“什么时候会悄无声息地错”——尤其是跨系统传数据、解析外部输入、跟数据库交互这三类场景。别信文档写的“支持 64 位”,得亲自跑 var_dump(PHP_INT_MAX) 看你那台机器到底认多少。











