?? 运算符在变量未定义时返回默认值且不报错,?: 则因变量未声明直接抛出 notice;??= 是 php 7.4+ 新增语法;数组展开在 php 7.2+ 保留原始键,此前强制重索引;and/or 优先级低于赋值,易致逻辑错误;++ 在 php 8 中改抛 error 异常但行为不变。

?? 和 ?: 在未定义变量时直接报错
PHP 7.0+ 引入 ?? 后,很多人误以为它只是 ?: 的“安全版”,但关键区别在于:未声明变量对 ?: 是致命错误,对 ?? 却是合法操作。
比如写 $name ?: 'guest',PHP 会立即抛出 Notice: Undefined variable: name;而 $name ?? 'guest' 完全没问题,直接返回 'guest'。
原因很简单:?? 只检查 isset(),?: 却要求变量已存在并参与布尔求值。线上环境若在 PHP 7.0 以下部署 ??,会直接触发 Fatal error,连错误页都吐不出来。
- 赋值为
0、''或false时,?:返回默认值,??返回原值 -
??=是 PHP 7.4+ 才支持的语法,PHP 7.3 及更早版本写$a ?? $a = 'x'会报错,必须改用$a ??= 'x'
扩展运算符 [...$arr] 在 PHP 7.2 前后键处理不一致
PHP 7.2 是分水岭——此前数组展开会强制重索引,此后默认保留原始键(字符串键始终保留,整数键仅在冲突时覆盖)。
比如 $a = [10 => 'x']; $b = [20 => 'y']; $result = [...$a, ...$b];:
PHP 7.1 及更早:结果是 [0 => 'x', 1 => 'y'](全部重排);
PHP 7.2+:结果是 [10 => 'x', 20 => 'y'](键完整保留)。
这个变化直接影响依赖键顺序的逻辑,比如用数组模拟稀疏映射、或与 JSON 键名强绑定的接口输出。
- 若代码依赖“展开后一定是连续数字键”,升级到 7.2+ 必须加
array_values()显式重排 - 合并含相同整数键的数组时,PHP 7.2+ 是后者覆盖前者;而 PHP 7.1 是后者直接被丢弃(因键重复被重排覆盖)
AND/OR 与 &&/|| 优先级差异导致赋值逻辑翻车
这不是“行为不同”,而是优先级陷阱:= 比 AND 和 OR 优先级高,却比 && 和 || 低。
所以 $q = TRUE and FALSE; 等价于 ($q = TRUE) and FALSE;,$q 最终是 TRUE;
而 $q = TRUE && FALSE; 等价于 $q = (TRUE && FALSE);,$q 是 FALSE。
这种差异在条件赋值+短路判断混合时极易出错,尤其在配置开关、权限校验等场景。
- 永远不要在赋值语句中混用
AND/OR,统一用&&/|| - 如果非要用
AND/OR(比如控制流程),就显式加括号:($q = TRUE) AND do_something();
递增操作符 ++ 在 PHP 8 中错误类型变了,但行为没变
++$i 和 $i++ 在 PHP 7 和 PHP 8 中表现完全一致:字符串转数字递增、null 递增得 1、布尔值无效。
唯一区别是错误兜底方式:PHP 7 对非法操作(如 ++[])抛 Fatal error,PHP 8 改为抛 Error 异常(属于 Throwable),理论上可 catch,但实际不该这么用。
真正该警惕的是隐式类型转换——比如对 '01' 递增,PHP 会按八进制解析成 1 再加 1 得 2,而不是字符串拼接。
- 递增前用
is_numeric()或filter_var($x, FILTER_VALIDATE_INT)校验类型 - 避免对
null、false、空数组等做递增,这通常暴露了业务逻辑漏洞
?? 在旧版 PHP 直接挂掉,而 AND 导致的赋值错位可能潜伏数月才在特定分支触发。版本切换前,务必用真实数据跑一遍边界 case,别只看 warning。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











