Skip to content

逻辑运算符

逻辑运算符把多个「是 / 否」拼成一个条件,结果仍然是布尔值。if、循环、提前返回都靠它。

php
<?php

$age = 20;
$hasTicket = true;

if ($age >= 18 && $hasTicket) {
    echo "可以入场\n";
}

if ($age < 18 || !$hasTicket) {
    echo "不能入场\n";
}

一览

运算符名称为 true 的情况
&&两边都为真
||至少一边为真
!右边为假
and&&,但优先级更低
or||,但优先级更低
xor异或两边一真一假

推荐日常用 &&||!and / or 很容易和赋值搅在一起,见下文。

真和假

逻辑运算会把操作数当成布尔值。下面这些在布尔上下文里是 false,其余一般是 true

当成
false
00.0
"""0"
[]
null
其他(包括 "false""0.0"[0]
php
<?php

var_dump((bool) 1);        // true
var_dump((bool) 0);        // false
var_dump((bool) "0");      // false
var_dump((bool) "false");  // true,非空字符串
var_dump((bool) []);       // false
var_dump((bool) [0]);      // true,数组里有元素

需要精确区分 0""null 时,用 ===,不要只靠逻辑运算的真假。比较规则见 比较运算符

&&、或 ||、非 !

php
<?php

$loggedIn = true;
$isAdmin = false;

var_dump($loggedIn && $isAdmin); // false,要两边都真
var_dump($loggedIn || $isAdmin); // true,有一边真就行
var_dump(!$isAdmin);             // true,取反

真值表(AB 为布尔值):

ABA && BA || B!A
truetruetruetruefalse
truefalsefalsetruefalse
falsetruefalsetruetrue
falsefalsefalsefalsetrue

xor 是「两个里恰好一个为真」:

php
<?php

var_dump(true xor true);   // false
var_dump(true xor false);  // true

实际项目里 xor 很少用,用 !== 往往更直观:$a !== $b(在两边已经是 bool 时)。

短路求值

&&|| 不一定会算右边:

  • $a && $b$a 为假时,整个式子已经是假,$b 不会执行
  • $a || $b$a 为真时,整个式子已经是真,$b 不会执行
php
<?php

function ping(): bool
{
    echo "ping\n";
    return true;
}

false && ping(); // 不会输出 ping
true || ping();  // 不会输出 ping
true && ping();  // 输出 ping

这很有用:先检查「值在不在」,再使用它,避免 Warning:

php
<?php

$config = ["host" => "localhost"];

if (isset($config["host"]) && $config["host"] !== "") {
    echo $config["host"], "\n";
}

isset() 为假时不会再读 $config["host"] 去做后面的比较。反过来写就失去这层保护。

and / or 同样短路。xor! 没有「跳过右边」这回事(! 只有一个操作数)。

&&and 的优先级陷阱

&& / || 的优先级高于赋值;and / or 的优先级低于赋值。于是:

php
<?php

$ok = true && false;
var_dump($ok); // false,先算 true && false,再赋给 $ok

$ok = true and false;
var_dump($ok); // true,实际是 ($ok = true) and false

第二行里 false 被算了,但结果没赋给 $ok。这类 bug 很隐蔽。

php
<?php

$found = $user = "xiaoming" or "guest";
// 实际是:($found = ($user = "xiaoming")) or "guest"

需要「逻辑结果赋给变量」时:

php
<?php

$ok = true && false;     // 推荐
$ok = (true and false);  // 用 and 就必须加括号

本指南统一用 && / ||

组合比较条件

逻辑运算经常和比较写在一起:

php
<?php

$age = 22;
$vip = true;
$banned = false;

$canEnter = $age >= 18 && !$banned && ($vip || $age >= 21);
var_dump($canEnter);

多层条件时用括号标明意图,或拆成中间变量:

php
<?php

$isAdult = $age >= 18;
$allowed = !$banned;
$canEnter = $isAdult && $allowed && ($vip || $age >= 21);

! 的优先级很高,!$a && $b(!$a) && $b,不是 !($a && $b)

书写建议

  • && / || / !,避开 and / or
  • 利用短路:先 isset / !== null,再读属性
  • 不要写 if ($x == true),直接 if ($x);要区分类型时用 === true
  • 否定复杂条件时,宁可 if (!$ready) 配一个语义清楚的变量,也不要一长串 ! 套括号
  • 多个条件优先拆行或拆变量,不要在一行里链太长

练习

  1. $score = 72$submitted = true,写出「已提交且分数及格」的条件并 var_dump
  2. 用短路:只有 $name 非空时才 echo 欢迎语(空字符串不输出)。
  3. 分别运行 $ok = false && true;$ok = false and true;,解释 $ok 为什么不同。
  4. 列出 0"0""""false"[] 各自 (bool) 转换结果。

上一篇:比较运算符
下一篇:三元运算符

基于 VitePress 构建的 PHP 基础学习指南