is_numeric() 在 php 8.3 中仍存在且行为更严格,仍接受 "123"、"-45.6"、"0x1a"、"1e3" 等,不适用于校验纯十进制整数;应改用 ctype_digit() 或正则 /^\d+$/,注意处理 null 和类型安全。

is_numeric() 在 PHP 8.3 中仍存在,但行为更严格
is_numeric() 没有被移除,但它在 PHP 8.3 中对“纯数字”的判定逻辑没变——依然返回 true 给 "123"、"-45.6"、"0x1A"、"1e3" 这类含进制、指数、符号的字符串。这不是 bug,是设计如此。很多人误以为它等价于“只含 0–9”,其实不是。
想校验“纯十进制整数字符串”?别用 is_numeric()
如果你的真实需求是:只接受 "123"、"0"、"404" 这种不含小数点、符号、空格、前导零(可选)的字符串,is_numeric() 会放行 "-123" 和 "12.3",导致逻辑漏洞。
- 用
ctype_digit($str):仅当字符串非空且每个字符都是0–9时返回true;注意它不接受空字符串、负号、小数点 - 用正则:
preg_match('/^\d+$/', $str),语义清晰,但略慢于ctype_digit - 若需支持前导零(如
"007"),ctype_digit仍可用;若要拒绝前导零,加额外判断:strlen($str) === 1 || $str[0] !== '0'
PHP 8.3 新增的 json_validate() 不适用于数字校验
json_validate() 只判断是否为合法 JSON 值,比如 "123"(带引号的字符串)或 123(裸数字)——但后者根本不是字符串,传进去会报错。它不能替代数字格式校验,别混用。
- 传
"123"(字符串)→ 返回true,但它只是个 JSON 字符串,不代表内容是数字 - 传
123(整数)→ 报TypeError,因为参数类型必须是string - 传
"-12.3"→ 也返回true,因为这是合法 JSON number 字符串,但不符合“纯十进制整数”要求
容易忽略的边界:空字符串、空白、null
升级到 PHP 8.3 后,is_numeric(null) 返回 false(和之前一致),但 ctype_digit(null) 会触发 Warning: ctype_digit(): Argument of type null given。这在旧代码里可能被静默吞掉,现在必须显式判空。
- 安全写法:
is_string($str) && ctype_digit($str) - 若变量可能为
null或int,先 cast:ctype_digit((string)$str),但要注意(string)null === "",而ctype_digit("")是false - PHP 8.3 对函数参数类型更敏感,这类隐式转换引发的 warning 已无法被
@抑制(取决于 error_reporting 设置)
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











