PHP中&&和||会短路,且必须依赖该特性写安全代码;它们优先级高于赋值运算符,而and/or优先级更低;!为松散取反,判空应优先用empty();三元运算符优先级最低,混合逻辑运算时须加括号。

PHP里&&和||到底会不会短路?
会,而且必须依赖这个特性写安全代码。PHP的&&(逻辑与)和||(逻辑或)是短路运算符:左边表达式结果已能确定整体真假时,右边根本不会执行。
常见错误是拿它当“顺序执行”用,比如:$user = getUser() && $user->isActive()——如果getUser()返回false或null,后面->isActive()直接报Fatal error: Call to a member function on bool。
- 正确写法是先判空:
($user = getUser()) && $user instanceof User && $user->isActive() - 或者拆成两步:
$user = getUser(); if ($user && $user->isActive()) { ... } -
&&优先级高于||,混用时务必加括号,比如$a || $b && $c等价于$a || ($b && $c),不是($a || $b) && $c
为什么and/or和&&/||不能随便换?
它们语义相同,但操作符优先级不同。and和or的优先级比赋值运算符=还低,而&&和||比=高得多。这是最容易翻车的地方。
典型错误:$success = $db->query($sql) or die('fail');——你以为是“查失败就die”,实际执行顺序是($success = $db->query($sql)) or die('fail'),即先赋值再判断,即使查询失败,$success已被设为false,or才触发die。看起来没问题,但换成&&就完全不对了:$success = $db->query($sql) && die('fail')会把die()返回值(null)赋给$success。
立即学习“PHP免费学习笔记(深入)”;
- 日常逻辑判断统一用
&&/||,更符合直觉、优先级可控 -
and/or只适合极少数控制流场景,比如do_something() or log_error()这种“成功就不执行右边”的意图 - IDE或PHPCS通常会警告
and/or在赋值语句中出现,别忽略
!取反要注意什么类型?
PHP的!是松散取反:它先把操作数转成布尔值再取反,而转换规则容易误判。比如!0、!'0'、![]、!null、!false全为true,但!' '(带空格字符串)是false,因为非空字符串转布尔是true。
最常踩的坑是检查数组是否为空:if (!$arr)看似简洁,但$arr = [0]也会进if分支(因为[0]转布尔是true,取反是false),而$arr = []确实为true。但如果你本意是“数组里没元素”,就该用empty($arr)或count($arr) === 0。
-
empty()会同时判断null、false、0、'0'、[]、'',比单纯!更贴近业务语义 - 对对象用
!会触发__isset()或__get()(如果定义了),可能引发意外调用 - 数值比较建议显式用
=== false或=== null,避免隐式转换干扰
三元运算符里嵌套&&/||怎么不写错?
三元运算符?:优先级比&&和||都低,所以$a && $b ? 'yes' : 'no'等价于($a && $b) ? 'yes' : 'no',但$a ? 'yes' : 'no' || $c会被解析为$a ? 'yes' : ('no' || $c),不是你想的“$a为真则'yes',否则'no'或$c”。
真实场景如权限判断:is_admin() || $user->hasRole('editor') ? 'allowed' : 'denied'——这里||先算,整个布尔结果再进三元,是对的;但换成is_admin() ? 'full' : $user->hasRole('editor') && 'limited'就危险了,因为&&比:优先级高,实际是is_admin() ? 'full' : ($user->hasRole('editor') && 'limited'),而'limited'字符串作为&&右操作数永远为真,结果恒为'limited'。
- 所有涉及三元和逻辑运算混合的地方,无条件加括号:
is_admin() ? 'full' : ($user->hasRole('editor') && 'limited') - 复杂条件建议拆成变量,比如
$canEdit = $user->hasRole('editor') && $post->isDraft(); $status = is_admin() ? 'full' : ($canEdit ? 'edit' : 'view'); - PHP 8.0+ 支持空合并联合运算符
??,和?:行为不同,注意别混淆:$x ?? 'default'只在$x为null时生效,$x ?: 'default'在$x为任意falsy值时都生效
逻辑运算看着简单,但优先级、类型转换、短路副作用这三点,任何一个没盯住,就可能让if走错分支、die没触发、或者数组判空失效。写的时候多看一眼执行顺序,比事后调试快得多。











