略微加速

PHP官方手册 - 互联网笔记

PHP - Manual: 逻辑运算符

2024-11-23

逻辑运算符

逻辑运算符
例子 名称 结果
$a and $b And(逻辑与) true,如果 $a$b 都为 true
$a or $b Or(逻辑或) true,如果 $a$b 任一为 true
$a xor $b Xor(逻辑异或) true,如果 $a$b 任一为 true,但不同时是。
! $a Not(逻辑非) true,如果 $a 不为 true
$a && $b And(逻辑与) true,如果 $a$b 都为 true
$a || $b Or(逻辑或) true,如果 $a$b 任一为 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 被赋给 $f,true 被忽略
// 等同于:(($f = false) or true)
$f false or true;

var_dump($e$f);

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

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

// 常量 true 被赋给 $h,false 被忽略
// 等同于:(($h = true) and false)
$h true and false;

var_dump($g$h);
?>

以上例程的输出类似于:

bool(true)
bool(false)
bool(false)
bool(true)
add a noteadd a note

User Contributed Notes 20 notes

up
269
Lawrence
14 years ago
Note that PHP's boolean operators *always* return a boolean value... as opposed to other languages that return the value of the last evaluated expression.

For example:

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

will print:

A: 1

in PHP -- as opposed to printing "A: avacado" as it would in a language like Perl or JavaScript.

This means you can't use the '||' operator to set a default value:

$a = $fruit || 'apple';

instead, you have to use the '?:' operator:

$a = ($fruit ? $fruit : 'apple');
up
54
dumitru at floringabriel dot com
5 years ago
In addition to what Lawrence said about assigning a default value, one can now use the Null Coalescing Operator (PHP 7). Hence when we want to assign a default value we can write:

$a = ($fruit ?? 'apple');
//assigns the $fruit variable content to $a if the $fruit variable exists or has a value that is not NULL, or assigns the value 'apple' to $a if the $fruit variable doesn't exists or it contains the NULL value
up
15
thisleenobleNOSPAMPLEASE at mac dot com
5 years ago
In order to kind of emulate the way javascript assigns the first non-false value in an expression such as this:

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

I wrote a little helper method that I put in a function dump library (here presented as a bare function):

<?php
function either($a, $b){
       
$val = $a ? $a : $b;
       
/*
             Yes, I know the fixed parameters in the function
             are redundant since I could just use func_get_args,
             but in most instances I'll be using this a replacement
             for the ternary operator and only passing two values.
             I don't want to invoke the additional process below
             unless I REALLY have to.
        */
       
$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;
    }
?>

Now instead of:

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

I write:

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

but more importantly, instead of writing:

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

I write:

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

or indeed:

$v = either($a, $b, $c, $d, $e, $f, $g, $h);
up
49
pepesantillan at gmail dot com
14 years ago
worth reading for people learning about php and programming: (adding extras <?php ?> to get highlighted code)

about the following example in this page manual:
Example#1 Logical operators illustrated

...
<?php
// "||" has a greater precedence than "or"
$e = false || true; // $e will be assigned to (false || true) which is true
$f = false or true; // $f will be assigned to false
var_dump($e, $f);

// "&&" has a greater precedence than "and"
$g = true && false; // $g will be assigned to (true && false) which is false
$h = true and false; // $h will be assigned to true
var_dump($g, $h);
?>
_______________________________________________end of my quote...

If necessary, I wanted to give further explanation on this and say that when we write:
$f = false or true; // $f will be assigned to false
the explanation:

"||" has a greater precedence than "or"

its true. But a more acurate one would be

"||" has greater precedence than "or" and than "=", whereas "or" doesnt have greater precedence than "=", so

<?php
$f
= false or true;

//is like writting

($f = false ) or true;

//and

$e = false || true;

is the same as

$e = (false || true);

?>

same goes for "&&" and "AND".

If you find it hard to remember operators precedence you can always use parenthesys - "(" and ")". And even if you get to learn it remember that being a good programmer is not showing you can do code with fewer words. The point of being a good programmer is writting code that is easy to understand (comment your code when necessary!), easy to maintain and with high efficiency, among other things.
up
5
egst
1 year ago
In response to Lawrence about || always returning a boolean:

Instead of

$x ? $x : 'fallback'

you can also use the "elvis operator":

$x ?: 'fallback'

which is useful in cases, where the left-hand side of the ternary operator is too long type, is too complex to calculate twice, or has side-effects.

It also combines nicely with the ?? operator, which is equivalent to an empty() check (both isset() and `!= false`):

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

instead of:

empty($x->y) ? $x->y : 'fallback'
up
16
momrom at freenet dot de
13 years ago
Evaluation of logical expressions is stopped as soon as the result is known.
If you don't want this, you can replace the and-operator by min() and the or-operator by max().

<?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 ) ); // Output: Expression false.
c( min( a( false ), b( true ) ) ); // Output: Expression is false.

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

This way, values aren't automaticaly converted to boolean like it would be done when using and or or. Therefore, if you aren't sure the values are already boolean, you have to convert them 'by hand':

<?php
c
( min( (bool) a( false ), (bool) b( true ) ) );
?>
up
14
phpnet at zc dot webhop dot net
9 years ago
This works similar to javascripts short-curcuit assignments and setting defaults. (e.g.  var a = getParm() || 'a default';)

<?php

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

?>

$a gets assigned $_GET['var'] if there's anything in it or it will fallback to 'a default'
Parentheses are required, otherwise you'll end up with $a being a boolean.
up
12
Andrew
14 years ago
> <?php
> your_function() or return "whatever";
>
?>

doesn't work because return is not an expression, it's a statement. if return was a function it'd work fine. :/
up
7
brian at zickzickzick dot com
8 years ago
This has been mentioned before, but just in case you missed it:

<?php
   
// Defaults --

    //If you're trying to gat 'Jack' from:
   
$jack = false or 'Jack';

   
// Try:
   
$jack = false or $jack = 'Jack';

   
//The other option is:
   
$jack = false ? false : 'Jack';
?>
up
5
peter dot kutak at NOSPAM dot gmail dot com
14 years ago
$test = true and false;     ---> $test === true
$test = (true and false);  ---> $test === false
$test = true && false;      ---> $test === false

NOTE: this is due to the first line actually being

($test = true) and false;

due to "&&" having a higher precedence than "=" while "and" has a lower one
up
2
anatoliy at ukhvanovy dot name
8 years ago
If you want to use the '||' operator to set a default value, like this:

<?php
$a
= $fruit || 'apple'; //if $fruit evaluates to FALSE, then $a will be set to TRUE (because (bool)'apple' == TRUE)
?>

instead, you have to use the '?:' operator:

<?php
$a
= ($fruit ? $fruit : 'apple');//if $fruit evaluates to FALSE, then $a will be set to 'apple'
?>

But $fruit will be evaluated twice, which is not desirable. For example fruit() will be called twice:
<?php
function fruit($confirm) {
    if(
$confirm)
        return
'banana';
}
$a = (fruit(1) ? fruit(1) : 'apple');//fruit() will be called twice!
?>

But since «since PHP 5.3, it is possible to leave out the middle part of the ternary operator» (http://www.php.net/manual/en/language.operators.comparison.php#language.operators.comparison.ternary), now you can code like this:

<?php
$a
= ($fruit ? : 'apple'); //this will evaluate $fruit only once, and if it evaluates to FALSE, then $a will be set to 'apple'
?>

But remember that a non-empty string '0' evaluates to FALSE!

<?php
$fruit
= '1';
$a = ($fruit ? : 'apple'); //this line will set $a to '1'
$fruit = '0';
$a = ($fruit ? : 'apple'); //this line will set $a to 'apple', not '0'!
?>
up
1
samantha at adrichem dot nu
7 years ago
<?php
    $res
|= true;
   
var_dump($res);
?>

does not/no longer returns a boolean (php 5.6) instead it returns int 0 or 1
up
1
void at informance dot info
8 years ago
To assign default value in variable assignation, the simpliest solution to me is:

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

It works because, first, $v is assigned the return value from my_function(), then this value is evaluated as a part of a logical operation:
* if the left side is false, null, 0, or an empty string, the right side must be evaluated and, again, because 'or' has low precedence, $v is assigned the string "default"
* if the left side is none of the previously mentioned values, the logical operation ends and $v keeps the return value from my_function()

This is almost the same as the solution from [phpnet at zc dot webhop dot net], except that his solution (parenthesis and double pipe) doesn't take advantage of the "or" low precedence.

NOTE: "" (the empty string) is evaluated as a FALSE logical operand, so make sure that the empty string is not an acceptable value from my_function(). If you need to consider the empty string as an acceptable return value, you must go the classical "if" way.
up
-9
drevilkuko at gmail dot com
6 years ago
using NULL coalesce operator:

<?php
$nc
= true == false ?? 'no';
var_dump($nc); // false

$nc = null ?? 'yes';
var_dump($nc); // yes

$username = null == false ?? 'no';
var_dump($nc); // true

$nc = $_GET['something'] ?? 'default';
var_dump($nc); // default

$nc = !isset($_GET['something']) ?? 'wtf';
var_dump($nc); // true

$nc = isset($_GET['something']) ?? 'wtf';
var_dump($nc); // false

$_POST['second'] = 'chain';
$nc = $_GET['first'] ?? $_POST['second'] ?? $_REQUEST['third'] ?? 'wtf';
var_dump($nc); // chain
?>
up
-5
vasko at tsintsev dot com
5 years ago
Here is something useful for OR ( or any other ) bitwise comparison:

$a = 0;
$b = 1;

printf('$a = %1$04b | $b = %2$04b ...  PROCESSED is: %3$s ( %3$04b )', $a, $b, ($a | $b));
up
-5
Manucyan
3 years ago
So...
A || B   may be different from  B || A

for exemple :

unset($a);
if (    ($a < 0)   ||   (!isset($a))   )
echo 'Hello!';  

//      return error:  "Notice: Undefined variable: a "

unset($a);
if (    (!isset($a))   ||    ($a < 0)  )
echo 'Hello!';  

//      return   'Hello!'

practical example with an age check over 17 years:
if (    (!isset($age))   ||    ($age < 17)  )
$error_age = true;

this example will not display a php error if the age is not entered
up
-6
mcodingset at outlook dot com
3 years ago
// __forFun ...
// Example Logical `or` operator

$a = true;                  // true|false or something for test :)
$b = "I'm a string result"; // use|test `string` or `object`

if (!$a or !$c = $b) {
    $c = 'Hey';
}

// print result
var_dump($c); // "I'm a string result"

Have Fun!
up
-10
moschris at gmail dot com
6 years ago
Unlike C++ and related languages, side effects in the left operand may NOT be used in the right operand.

e.g. if ($a=1 && $a>0)
will produce an unassigned error if $a has not previously been assigned a value.
up
-20
4077
7 years ago
Assign a value to a variable if it isn't defined

<?php

isset($x) || $x = 123;

print
$x; // 123

?>

instead of:
<?php

if ( !isset($x)) {
   
$x = 123;
}

// or

$x = isset($x) ? $x : 123;

// or

$x = isset($x) ?: 123;
?>

editor's note: In PHP 7 you could use the coalesce operator and do:
<?php
$x
= $x ?? 123;
up
-37
paranoiq at centrum dot cz
14 years ago
and, or and xor can be used as conditional constructs:

<?php
// do_that() is executed only if do_this() returns false
if($something) do_this() or do_that();
// $b is assigned to $b, do_that() is executed if $b is false
if($something) $a = $b or do_that();

// do_that() is executed only if do_this() returns true
if($something) do_this() and do_that();
// $b is assigned to $b, do_that() is executed if $b is true
if($something) $a = $b and do_that();

// both do_that() and do_this() are executed..
if($something) do_this() xor do_that();
// .. so the behaviour is same as:
if($something) {
   
do_this();
   
do_that();
}
?>

for understanding what happens if $b is NULL or do_this() returns NULL, read the avbentem's comment on NULL type. generaly speaking, NULL is threated like false in most cases.

官方地址:https://www.php.net/manual/en/language.operators.logical.php

北京半月雨文化科技有限公司.版权所有 京ICP备12026184号-3