PHP Conference Japan 2024

逻辑运算符

逻辑运算符
示例 名称 结果
$a and $b 如果 $a$b 均为 true,则结果为 true
$a or $b 如果 $a$btrue,则结果为 true
$a xor $b 异或 如果 $a$b 中只有一个为 true,则结果为 true
! $a 如果 $a 不为 true,则结果为 true
$a && $b 如果 $a$b 均为 true,则结果为 true
$a || $b 如果 $a$btrue,则结果为 true

"and" 和 "or" 运算符存在两种不同的变体,原因在于它们的优先级不同。(参见 运算符优先级)。

示例 #1 逻辑运算符示例

<?php

// --------------------
// foo() 永远不会被调用,因为这些运算符是短路运算符

$a = (false && foo());
$b = (true || foo());
$c = (false and foo());
$d = (true or foo());

// --------------------
// "||" 的优先级高于 "or"

// 表达式 (false || true) 的结果被赋值给 $e
// 等价于:($e = (false || true))
$e = false || true;

// 在 "or" 运算发生之前,常量 false 被赋值给 $f
// 等价于:(($f = false) or true)
$f = false or true;

var_dump($e, $f);

// --------------------
// "&&" 的优先级高于 "and"

// 表达式 (true && false) 的结果被赋值给 $g
// 等价于:($g = (true && false))
$g = true && false;

// 在 "and" 运算发生之前,常量 true 被赋值给 $h
// 等价于:(($h = true) and false)
$h = true and false;

var_dump($g, $h);
?>

以上示例将输出类似以下内容

bool(true)
bool(false)
bool(false)
bool(true)
添加注释

用户贡献的注释 14 条注释

Lawrence
17 年前
请注意,PHP 的布尔运算符 *始终* 返回布尔值……这与其他返回最后一个计算表达式值的语言不同。

例如

$a = 0 || 'avacado';
print "A: $a\n";

将在 PHP 中打印

A: 1

——而不是像 Perl 或 JavaScript 这样的语言那样打印“A: avacado”。

这意味着您不能使用 '||' 运算符设置默认值

$a = $fruit || 'apple';

相反,您必须使用 '?:' 运算符

$a = ($fruit ? $fruit : 'apple');
dumitru at floringabriel dot com
7 年前
除了 Lawrence 关于分配默认值所说的内容之外,现在还可以使用空值合并运算符 (PHP 7)。因此,当我们想要分配默认值时,可以这样写

$a = ($fruit ?? 'apple');
//如果 $fruit 变量存在或具有非 NULL 值,则将 $fruit 变量的内容赋值给 $a,或者如果 $fruit 变量不存在或包含 NULL 值,则将值 'apple' 赋值给 $a
thisleenobleNOSPAMPLEASE at mac dot com
7 年前
为了模拟 JavaScript 在类似以下表达式的语句中分配第一个非假值的的方式

var v = a || b || c || d;

我编写了一个小的辅助方法,并将其放在一个函数转储库中(此处以裸函数形式呈现)

<?php
function either($a, $b){
$val = $a ? $a : $b;
/*
是的,我知道函数中的固定参数
是多余的,因为我只需使用 func_get_args 即可,
但在大多数情况下,我将使用此方法替换
三元运算符,并且只传递两个值。
除非我 *真的* 需要,否则我不想调用下面的额外处理过程。
*/
$args = func_get_args();
if(
$val === false && count($args) > 2){
$args = array_slice($args, 2);

foreach(
$args as $arg){
if(
$arg !== false){
$val = $arg;
break;
}
}
}
return
$val;
}
?>

现在,不用写

$v = $a ? $a : $b;

我可以写

$v = either($a, $b);

但更重要的是,不用写

$v = $a ? $a : ($b ? $b : $c);

我可以写

$v = either($a, $b, $c);

或者实际上

$v = either($a, $b, $c, $d, $e, $f, $g, $h);
pepesantillan at gmail dot com
16 年前
值得学习 PHP 和编程的人阅读:(添加额外的 <?php ?> 以突出显示代码)

关于此页面手册中的以下示例
示例 #1 逻辑运算符示例

...
<?php
// "||" 的优先级高于 "or"
$e = false || true; // $e 将被赋值为 (false || true),即 true
$f = false or true; // $f 将被赋值为 false
var_dump($e, $f);

// "&&" 的优先级高于 "and"
$g = true && false; // $g 将被赋值为 (true && false),即 false
$h = true and false; // $h 将被赋值为 true
var_dump($g, $h);
?>
_______________________________________________我的引语结束...

如有必要,我想进一步解释一下,并说明当我们写
$f = false or true; // $f 将被赋值为 false
解释

"||" 的优先级高于 "or"

确实如此。但更准确的说法是

"||" 的优先级高于 "or" 和 "=",而 "or" 的优先级并不高于 "=",所以

<?php
$f
= false or true;

// 等同于

($f = false ) or true;

// 以及

$e = false || true;

等同于

$e = (false || true);

?>

"&&" 和 "AND" 也是同样的道理。

如果你觉得难以记住运算符的优先级,你始终可以使用圆括号 - "(" 和 ")"。即使你记住了优先级,也要记住,优秀的程序员并非以写出代码量最少的代码为目标。优秀的程序员更注重编写易于理解(必要时添加注释!)、易于维护且效率高的代码,以及其他一些因素。
egst
3 年前
回复 Lawrence 关于 || 总是返回布尔值的问题

除了

$x ? $x : 'fallback'

你还可以使用 "Elvis 运算符"

$x ?: 'fallback'

这在一些情况下非常有用,比如三元运算符的左侧表达式类型过长、计算两次过于复杂或存在副作用。

它还可以很好地与 ?? 运算符结合使用,?? 运算符等效于 empty() 检查(同时检查 isset() 和 `!= false`)

$x->y ?? null ?: 'fallback';

代替

empty($x->y) ? $x->y : 'fallback'
martinholtcbi at gmail dot com
1 年前
在 PHP 中,|| 运算符始终只返回布尔值。对于可链式赋值运算符,请使用 ?: "Elvis" 运算符。

JavaScript
let a = false;
let b = false;
let c = true;
let d = false;
let e = a || b || c || d;
// e === c

<?PHP
$a
= false;
$b = false;
$c = true;
$d = false;
$e = $a ?: $b ?: $c ?: $d;
// $e === $c
?>

感谢 @egst 和其他人的见解。这只是针对(以前)像我一样迷失的 JavaScript 开发人员的重新表述。
phpnet at zc dot webhop dot net
11 年前
这类似于 JavaScript 的短路赋值和设置默认值。(例如 var a = getParm() || 'a default';)

<?php

($a = $_GET['var']) || ($a = 'a default');

?>

$a 如果 $_GET['var'] 中有值则赋值 $_GET['var'],否则回退到 'a default'
需要括号,否则 $a 将最终成为布尔值。
momrom at freenet dot de
15 年前
逻辑表达式的求值一旦结果已知就会停止。
如果你不希望这样,你可以用 min() 替换 and 运算符,用 max() 替换 or 运算符。

<?php
function a($x) { echo 'Expression '; return $x; }
function
b($x) { echo 'is '; return $x; }
function
c($x) { echo $x ? 'true.' : 'false.' ;}

c( a( false ) and b( true ) ); // 输出:Expression false.
c( min( a( false ), b( true ) ) ); // 输出:Expression is false.

c( a( true ) or b( true ) ); // 输出:Expression true.
c( max( a( true ), b( true ) ) ); // 输出:Expression is true.
?>

这样,值就不会像使用 and 或 or 时那样自动转换为布尔值。因此,如果你不确定值是否已经是布尔值,则必须“手动”转换它们。

<?php
c
( min( (bool) a( false ), (bool) b( true ) ) );
?>
Andrew
17 年前
> <?php
> your_function() or return "whatever";
>
?>

不起作用,因为 return 不是表达式,而是一个语句。如果 return 是一个函数,它就可以正常工作了。:/
anatoliy at ukhvanovy dot name
10 年前
如果你想使用 '||' 运算符来设置默认值,像这样

<?php
$a
= $fruit || 'apple'; // 如果 $fruit 求值为 FALSE,则 $a 将被设置为 TRUE(因为 (bool)'apple' == TRUE)
?>

相反,您必须使用 '?:' 运算符

<?php
$a
= ($fruit ? $fruit : 'apple');// 如果 $fruit 求值为 FALSE,则 $a 将被设置为 'apple'
?>

但是 $fruit 将被评估两次,这是不可取的。例如 fruit() 将被调用两次
<?php
function fruit($confirm) {
if(
$confirm)
return
'banana';
}
$a = (fruit(1) ? fruit(1) : 'apple');// fruit() 将被调用两次!
?>

但是由于“从 PHP 5.3 开始,可以省略三元运算符的中间部分”(https://php.net/manual/en/language.operators.comparison.php#language.operators.comparison.ternary),现在你可以这样编码

<?php
$a
= ($fruit ? : 'apple'); // 这将只评估 $fruit 一次,如果它求值为 FALSE,则 $a 将被设置为 'apple'
?>

但请记住,非空字符串 '0' 求值为 FALSE!

<?php
$fruit
= '1';
$a = ($fruit ? : 'apple'); // 这行代码将 $a 设置为 '1'
$fruit = '0';
$a = ($fruit ? : 'apple'); // 这行代码将 $a 设置为 'apple',而不是 '0'!
?>
peter dot kutak at NOSPAM dot gmail dot com
17 年前
$test = true and false; ---> $test === true
$test = (true and false); ---> $test === false
$test = true && false; ---> $test === false

注意:这是因为第一行实际上是

($test = true) and false;

因为 "&&" 的优先级高于 "=",而 "and" 的优先级低于 "="
void at informance dot info
10 年前
要为变量赋值设置默认值,对我来说最简单的解决方案是

<?php
$v
= my_function() or $v = "default";
?>

它之所以有效,是因为首先,$v 被赋值为 my_function() 的返回值,然后此值被评估为逻辑运算的一部分
* 如果左侧为 false、null、0 或空字符串,则必须评估右侧,并且由于 'or' 的优先级较低,因此 $v 被赋值为字符串 "default"


* 如果左侧的值不属于之前提到的任何值,则逻辑运算结束,并且 $v 保留来自 my_function() 的返回值。

这几乎与 [phpnet at zc dot webhop dot net] 中的解决方案相同,除了他的解决方案(括号和双竖线)没有利用“或”的低优先级。

注意:""(空字符串)被评估为 FALSE 逻辑操作数,因此请确保空字符串不是 my_function() 的可接受返回值。如果您需要将空字符串视为可接受的返回值,则必须使用经典的“if”方式。
brian at zickzickzick dot com
11 年前
之前已经提到过这一点,但以防万一您错过了。

<?php
// 默认值 --

//如果您尝试从以下获取 'Jack':
$jack = false or 'Jack';

// 请尝试:
$jack = false or $jack = 'Jack';

//另一个选项是:
$jack = false ? false : 'Jack';
?>
samantha at adrichem dot nu
9 年前
<?php
$res
|= true;
var_dump($res);
?>

不会/不再返回布尔值(php 5.6),而是返回整数 0 或 1。
To Top