PHP Conference Japan 2024

邏輯運算子

邏輯運算子
範例 名稱 結果
$a and $b And(且) 如果 $a$b 皆為 true,則為 true
$a or $b Or(或) 如果 $a$b 其中之一為 true,則為 true
$a xor $b Xor(互斥或) 如果 $a$b 其中之一為 true,但不同時為 true,則為 true
! $a Not(非) 如果 $a 不為 true,則為 true
$a && $b And(且) 如果 $a$b 皆為 true,則為 true
$a || $b Or(或) 如果 $a$b 其中之一為 true,則為 true

「且」和「或」運算子有兩種不同變化的原因是它們的運算優先順序不同。(請參閱 運算子優先順序。)

範例 #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;

// 常數 false 會在 "or" 運算發生之前被賦值給 $f
// 等同於:(($f = false) or true)
$f = false or true;

var_dump($e, $f);

// --------------------
// "&&" 的優先順序高於 "and"

// 表達式 (true && false) 的結果會被賦值給 $g
// 等同於:($g = (true && false))
$g = true && false;

// 常數 true 會在 "and" 運算發生之前被賦值給 $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";

會印出

A: 1

在 PHP 中 -- 與在 Perl 或 JavaScript 等語言中印出 "A: avacado" 不同。

這表示您不能使用 '||' 運算子來設定預設值

$a = $fruit || 'apple';

您必須使用 '?:' 運算子

$a = ($fruit ? $fruit : 'apple');
dumitru at floringabriel dot com
7 年前
除了 Lawrence 提到的指定預設值之外,現在可以使用 Null 合併運算子 (PHP 7)。因此,當我們想要指定預設值時,可以這樣寫

$a = ($fruit ?? 'apple');
//如果 $fruit 變數存在或具有非 NULL 的值,則將 $fruit 變數的內容指定給 $a;如果 $fruit 變數不存在或包含 NULL 值,則將值 'apple' 指定給 $a
thisleenobleNOSPAMPLEASE at mac dot com
7 年前
為了模擬 JavaScript 在像這樣的表達式中指定第一個非 false 值的方式

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);
16 年前

值得學習 PHP 和程式設計的人閱讀:(添加額外的 <?php ?> 以取得程式碼高亮)
關於此頁面手冊中的以下範例

...
<?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');

?>

如果 `$_GET['var']` 中有任何值,`$a` 將被賦予該值;否則,它將使用預設值 'a default'。
括號是必需的,否則 `$a` 最終會變成布林值。
momrom at freenet dot de
15 年前
邏輯表達式的求值會在結果確定後立即停止。
如果您不希望這樣,您可以用 `min()` 取代 `and` 運算子,用 `max()` 取代 `or` 運算子。

<?php
function a($x) { echo '表達式 '; return $x; }
function
b($x) { echo '是 '; return $x; }
function
c($x) { echo $x ? 'true。' : 'false。' ;}

c( a( false ) and b( true ) ); // 輸出:表達式 false。
c( min( a( false ), b( true ) ) ); // 輸出:表達式 是 false。

c( a( true ) or b( true ) ); // 輸出:表達式 true。
c( max( a( true ), b( true ) ) ); // 輸出:表達式 是 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.dev.org.tw/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] 的解決方案幾乎相同,只是他的解決方案(括號和雙豎線)沒有利用 "or" 的低優先順序。

注意:""(空字串)會被評估為 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