PHP 8.1中整数0是明确定义的falsy值,行为合理;字符串'0'才是隐性陷阱,因被误判为falsy导致逻辑错误,需显式拦截或类型转换。

PHP 8.1 中,三元运算符对 0 的处理方式与历史版本一致:整数 0 和字符串 '0' 都被判定为 falsy 值,但它们的“翻车点”完全不同——前者是合理逻辑,后者才是最常踩的坑。
整数 0 是正常 falsy,无需特殊处理
整数 0 属于 PHP 明确定义的 falsy 值(和 false、null、空数组等并列),所以:
-
$count = 0; $result = $count ?: 'no data';→ 返回'no data',符合预期 - 这种行为在业务中往往合理,比如“商品库存为 0”确实可视为“无货”,直接 fallback 默认值是安全的
- 若业务上
0是有效值(如“用户积分余额为 0”),就不能依赖?:判断,而应改用显式条件
字符串 '0' 是隐性陷阱,必须主动拦截
这是 PHP 最反直觉的设计之一:'0'(字符串零)被当作 falsy,但 '00'、'0.0'、'false' 却是 truthy。例如:
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
-
$age = '0'; $final = $age ?: 18;→ 得到18,而非'0',用户填了“年龄 0”却被当成“未填写” -
??运算符对此无效,因为'0'不是null或未定义,$age ?? 18仍返回'0' - 正确写法是严格排除:
($age !== '' && $age !== '0') ? $age : 18 - 或统一转类型后判断:
(int)$age ?: 18(注意会把'05'变成5,需按需取舍)
Excel/表单导入时,0、'0'、空、null 常混在一起
从 Excel 或 POST 表单读取数据时,一个“空单元格”可能表现为 null、''、0 或 '0',全被 ?: 当作假:
立即学习“PHP免费学习笔记(深入)”;
-
$score = $row['score'] ?: 0;→ 若原始是'0'(真实零分),会被覆盖成0;若原始是null,还会触发 Notice - 安全做法是组合判断:
isset($row['score']) && $row['score'] !== '' && $row['score'] !== '0' ? $row['score'] : 0 - 更健壮的方案是先归一化:
$score = filter_var($row['score'], FILTER_VALIDATE_INT) !== false ? (int)$row['score'] : 0;
嵌套三元中 '0' 会导致逻辑跳变
PHP 三元是左结合,A ? B : C ? D : E 实际解析为 (A ? B : C) ? D : E。一旦中间值是 '0',整个左侧变成 false,直接跳到最终 E:
-
$role = '0'; $level = $role === 'admin' ? 'A' : $role === 'editor' ? 'E' : 'U';→ 结果是'U',完全绕过editor判断 - 修复方法只有两个:
– 加括号:$role === 'admin' ? 'A' : ($role === 'editor' ? 'E' : 'U')
– 改用match(PHP 8.0+):match($role) { 'admin' => 'A', 'editor' => 'E', default => 'U' }


















