?? 只判断变量是否已声明且不为 null,0、false、'' 等 falsy 值均原样返回;?: 对未定义变量报错,且将所有 falsy 值(含 0、false、'')视为假而取右值;二者混用需括号明确优先级,否则 ?? 在 ?: 右侧几无生效机会。

?? 只管 null 和未定义变量,?: 会把 0、false、''、[] 全部当“假”处理——用错一个,计数、开关、API 状态码就可能出错。
?? 是 isset() 的语法糖,不是“取非空”
它只做一件事:左侧变量是否已声明且不为 null。其他所有 falsy 值(比如 0、false、空字符串)都原样返回。
-
$count = 0; echo $count ?? 1;输出0(正确) -
$name = ''; echo $name ?? 'guest';输出''(不是'guest') -
$userConfig未定义时,$userConfig ?? []安全执行,不报Notice: Undefined variable - 链式写法
$_GET['id'] ?? $_POST['id'] ?? '0'是从左到右找第一个非null且已声明的值
?: 是 empty() 的快捷写法,本质是布尔求值
它必须先读取左侧表达式才能判断真假,所以未定义变量直接触发 Notice;而且只要值被 PHP 认为是 falsy,就跳右边。
-
$count = 0; echo $count ?: 1;输出1(常见坑:计数器归零被当成“无值”) -
$status = false; echo $status ?: 'active';输出'active'(开关状态被误判) -
$undefined ?: 'default'会立刻报Notice: Undefined variable: undefined -
$a ?: $b ?: $c是左结合:($a ?: $b) ?: $c,不是“取第一个非空”,而是“取第一个 truthy”
混用 ?? 和 ?: 会因优先级出错
?? 优先级低于 ?:,但高于赋值运算符;混写不加括号,PHP 会按固定规则解析,结果往往和直觉相反。
-
$_GET['x'] ?: $_POST['x'] ?? '0'实际等价于($_GET['x'] ?: $_POST['x']) ?? '0',右边的??几乎没机会生效 - 想表达“先 fallback 到 POST,再 fallback 到默认值”,必须写成
$_GET['x'] ?? ($_POST['x'] ?? '0') - 线上若跑在 PHP ?? 会直接 Fatal error,而
?:在 5.3+ 就支持
空字符串、0、false 这类值需要单独处理
?? 和 ?: 都不解决“过滤空字符串”问题。它们的设计目标不同,强行塞进一个运算符里处理,只会让逻辑变脆。
- 要“有值且非空字符串”,得显式写:
($name !== '' && $name !== null) ? $name : 'guest' - 或封装函数:
function nonEmpty($v, $d) { return $v !== '' && $v !== null ? $v : $d; } - 别依赖
?:来“排除空字符串”,因为它连'0'都会当成 falsy(注意字符串'0'和整数0都被empty()判定为 true)
真正容易被忽略的点是:这两个运算符根本不在同一抽象层上——?? 解决的是“变量是否存在”,?: 解决的是“值是否为真”。拿它们互换,就像用温度计量长度,刻度再准也没用。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











