混用&&和||不加括号必然出错,因php优先级为! > && > ||,但人脑难记且代码不应依赖;如$logged_in && $is_admin || $has_edit实际等价于($logged_in && $is_admin) || $has_edit,而非$logged_in && ($is_admin || $has_edit),易致权限漏洞。

混用 && 和 || 时,不加括号几乎必然出错——PHP 的优先级是 ! > && > ||,但人脑记不住,代码也不该依赖它。
为什么 $logged_in && $is_admin || $has_edit 不是你想的逻辑
这个表达式实际等价于 ($logged_in && $is_admin) || $has_edit,而不是你心里想的“已登录且(是管理员或有编辑权限)”。一旦 $has_edit 为 true,哪怕用户没登录、也不是管理员,整个条件也成立。这在权限校验里是严重漏洞。
- 必须写成
$logged_in && ($is_admin || $has_edit) - 哪怕子条件看起来“简单”,也别省括号——
||左右两边语义上是并列关系,括号是语义锚点,不是可选项 - IDE 和静态分析工具(如 PHPStan)通常不会报这种错,运行时行为异常才暴露,调试成本高
&& 和 || 的短路行为会影响副作用执行
短路不是优化技巧,而是求值规则:左边结果已能决定整体真假时,右边根本不会运行。如果右边有函数调用、赋值或数据库操作,它可能被跳过。
-
$user = find_user($id) && $user->activate();:若find_user()返回 false,activate()不会调用 -
$cache = get_cache($key) || $cache = compute_expensive_data();:只有缓存未命中时才计算 - 但别写
$a && $b = 123这类赋值——可读性差,且容易和and混淆;真要兜底,用三元或 if 更清晰
别把 and/or 和 &&/|| 当同义词混用
and 和 or 优先级极低,低于赋值操作符 =,混用会导致求值顺序完全失控。
-
$success = connect_db() and log_success();等价于($success = connect_db()) and log_success();,log 总会执行 -
$success = connect_db() && log_success();等价于$success = (connect_db() && log_success());,log 只在连接成功时执行,且$success是布尔结果 - 在
if条件里一律用&&和||;and/or仅限极少数副作用链式控制场景,且必须确认团队共识
类型隐式转换会让条件判断“看似成立”实则危险
&& 和 || 对操作数做松散布尔转换,"0"、0、[]、null 都算 false——但业务上它们可能都是合法值。
- 验证表单字段时,
!empty($_POST['age'])会把年龄"0"拦住,错误 - 更安全的是:
isset($_POST['age']) && is_numeric($_POST['age']) && $_POST['age'] >= 0 - 涉及字符串比较时,优先用
===配合trim(),例如strlen(trim($name)) > 0
最常被忽略的其实是括号的强制语义作用:它不是为了“让 PHP 看懂”,而是为了让下一个接手的人一眼看懂你的逻辑分组意图。哪怕只有一处没括,整条条件就可能脱离控制。这不是风格问题,是协作底线。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











