In PHP 7, the following snippet strangely prints true:
$b = true and false;
var_dump($b);
However, if I cast it, it correctly prints false:
$b = (bool)(true and false);
var_dump($b);
What is the phenomenon that causes this to happen?
It's not the cast that's doing it, it's the parentheses. and has lower precedence than =, so your first statement is treated as
($b = true) and false;
You need to write:
$b = (true and false);
or
$b = true && false;
&& and and are equivalent except for their precedence (the same goes for || and or).
It's not the casting, but the parentheses:
$b = (true and false);
var_dump($b);
# => bool(false)
This is because = binds more tightly than and or or.
Alternatively, this also works:
$b = true && false;
var_dump($b);
# => bool(false)
&& and || bind more tightly than =.
Related
I remember reading a while back in regards to logical operators that in the case of OR, using || was better than or (or vice versa).
I just had to use this in my project when it came back to me, but I can't remember which operator was recommended or if it was even true.
Which is better and why?
There is no "better" but the more common one is ||. They have different precedence and || would work like one would expect normally.
See also: Logical operators (the following example is taken from there):
// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;
// The constant false is assigned to $f and then true is ignored
// Acts like: (($f = false) or true)
$f = false or true;
They are used for different purposes and in fact have different operator precedences. The && and || operators are intended for Boolean conditions, whereas and and or are intended for control flow.
For example, the following is a Boolean condition:
if ($foo == $bar && $baz != $quxx) {
This differs from control flow:
doSomething() or die();
The difference between respectively || and OR and && and AND is operator precedence :
$bool = FALSE || TRUE;
interpreted as ($bool = (FALSE || TRUE))
value of $bool is TRUE
$bool = FALSE OR TRUE;
interpreted as (($bool = FALSE) OR TRUE)
value of $bool is FALSE
$bool = TRUE && FALSE;
interpreted as ($bool = (TRUE && FALSE))
value of $bool is FALSE
$bool = TRUE AND FALSE;
interpreted as (($bool = TRUE) AND FALSE)
value of $bool is TRUE
Source: http://wallstreetdeveloper.com/php-logical-operators/
Here is sample code for working with logical operators:
<html>
<head>
<title>Logical</title>
</head>
<body>
<?php
$a = 10;
$b = 20;
if ($a>$b)
{
echo " A is Greater";
}
elseif ($a<$b)
{
echo " A is lesser";
}
else
{
echo "A and B are equal";
}
?>
<?php
$c = 30;
$d = 40;
//if (($a<$c) AND ($b<$d))
if (($a<$c) && ($b<$d))
{
echo "A and B are larger";
}
if (isset($d))
$d = 100;
echo $d;
unset($d);
?>
<?php
$var1 = 2;
switch($var1)
{
case 1: echo "var1 is 1";
break;
case 2: echo "var1 is 2";
break;
case 3: echo "var1 is 3";
break;
default: echo "var1 is unknown";
}
?>
</body>
</html>
I know it's an old topic but still. I've just met the problem in the code I am debugging at work and maybe somebody may have similar issue...
Let's say the code looks like this:
$positions = $this->positions() || [];
You would expect (as you are used to from e.g. javascript) that when $this->positions() returns false or null, $positions is empty array. But it isn't. The value is TRUE or FALSE depends on what $this->positions() returns.
If you need to get value of $this->positions() or empty array, you have to use:
$positions = $this->positions() or [];
EDIT:
The above example doesn't work as intended but the truth is that || and or is not the same... Try this:
<?php
function returnEmpty()
{
//return "string";
//return [1];
return null;
}
$first = returnEmpty() || [];
$second = returnEmpty() or [];
$third = returnEmpty() ?: [];
var_dump($first);
var_dump($second);
var_dump($third);
echo "\n";
This is the result:
bool(false)
NULL
array(0) {
}
So, actually the third option ?: is the correct solution when you want to set returned value or empty array.
$positions = $this->positions() ?: [];
Tested with PHP 7.2.1
I don't think one is inherently better than another one, but I would suggest sticking with || because it is the default in most languages.
EDIT: As others have pointed out there is indeed a difference between the two.
There is nothing bad or better, It just depends on the precedence of operators. Since || has higher precedence than or, so || is mostly used.
Some languages use short-circuit, and others use full Boolean evaluation (if you know, this is similar to the directive $B in Pascal).
Explanations:
function A(){
...Do something..
return true;
}
function B(){
...Do something..
return true;
}
if ( A() OR B() ) { .....
In this example the function B() will never be executed. Since the function A() returns TRUE, the result of the OR statement is known from the first part without it being necessary to evaluate the second part of the expression.
However with ( A() || B() ), the second part is always evaluated regardless of the value of the first.
For optimized programming, you should always use OR which is faster (except for the case when the first part returns false and second part actually needs to be evaluated).
if($post_id === null) {
$this->db->insert($data);
!isset($data[$this->page_id]) || $data[$this->page_id] = NULL;
}
Logical operators perform short-circuit evaluation.
If the first part of a logical OR is true, the whole expression is true and hence, there is no need to evaluate the second part.
What it is doing is equivalent to:
if(isset($data[$this->page_id])){
$data[$this->page_id] = NULL
}
To give an example of how this works, from the documentation:
// foo() will never get called as those operators are short-circuit
$a = (false && foo());
$b = (true || foo());
I encountered a weird bug in PHP 5.4.3
var_dump(false OR true); // boolean true // OK
$a = false OR true;
var_dump($a); // boolean false // !!????
$a = true OR false;
var_dump($a); // boolean true // OK
$a = false || true;
var_dump($a); // boolean true // OK
Does anyone know how the second result came up!?
Thanks :)
or and and have a lower precedence then =.
This is effectively:
($a = false) OR true;
($a = true) OR false;
$a = (false || true);
Note that this is the reason people tend to use or die() constructs (which really, really, really should be or trigger_error()'s, die's on errors have NO place in code): if the result of the left hand assignment (the resulting value in $a in this case) is false, perform the right hand side.
Compare:
$a = false or print("what is going on?");
// prints 'what is going on?', $a === false
$a = true or print("what is going on?");
// prints nothing, $a === true
It is called the precedence of the operators.
See here
So
$a = false OR true;
is the same as
($a = false) OR true;
etc...
This is a weird one. I'm working inside a PHP theme file in WordPress.
$a = false;
$b = true;
$c = $a OR $b;
$c is false
But
$c = $a || $b;
$c is, correctly, true.
I can create a function
function checkor($a, $b)
{
return $a OR $b;
}
And this will correctly return true for the values above.
Any idea why the php OR operand doesn't appear to work in a WordPress theme template file? (I'm running MAMP Pro on a Mac, PHP version 5.2.13.)
Check the PHP manual http://www.php.net/manual/en/language.operators.logical.php
// "||" has a greater precedence than "or"
// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;
// The constant false is assigned to $f and then true is ignored
// Acts like: (($f = false) or true)
$f = false or true;
This has nothing to do with Wordpress, and is actually the way PHP works.
It's called Operator Precedence.
To quote the PHP docs:
// "||" has a greater precedence than "or"
// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;
// The constant false is assigned to $f and then true is ignored
// Acts like: (($f = false) or true)
$f = false or true;
I remember reading a while back in regards to logical operators that in the case of OR, using || was better than or (or vice versa).
I just had to use this in my project when it came back to me, but I can't remember which operator was recommended or if it was even true.
Which is better and why?
There is no "better" but the more common one is ||. They have different precedence and || would work like one would expect normally.
See also: Logical operators (the following example is taken from there):
// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;
// The constant false is assigned to $f and then true is ignored
// Acts like: (($f = false) or true)
$f = false or true;
They are used for different purposes and in fact have different operator precedences. The && and || operators are intended for Boolean conditions, whereas and and or are intended for control flow.
For example, the following is a Boolean condition:
if ($foo == $bar && $baz != $quxx) {
This differs from control flow:
doSomething() or die();
The difference between respectively || and OR and && and AND is operator precedence :
$bool = FALSE || TRUE;
interpreted as ($bool = (FALSE || TRUE))
value of $bool is TRUE
$bool = FALSE OR TRUE;
interpreted as (($bool = FALSE) OR TRUE)
value of $bool is FALSE
$bool = TRUE && FALSE;
interpreted as ($bool = (TRUE && FALSE))
value of $bool is FALSE
$bool = TRUE AND FALSE;
interpreted as (($bool = TRUE) AND FALSE)
value of $bool is TRUE
Source: http://wallstreetdeveloper.com/php-logical-operators/
Here is sample code for working with logical operators:
<html>
<head>
<title>Logical</title>
</head>
<body>
<?php
$a = 10;
$b = 20;
if ($a>$b)
{
echo " A is Greater";
}
elseif ($a<$b)
{
echo " A is lesser";
}
else
{
echo "A and B are equal";
}
?>
<?php
$c = 30;
$d = 40;
//if (($a<$c) AND ($b<$d))
if (($a<$c) && ($b<$d))
{
echo "A and B are larger";
}
if (isset($d))
$d = 100;
echo $d;
unset($d);
?>
<?php
$var1 = 2;
switch($var1)
{
case 1: echo "var1 is 1";
break;
case 2: echo "var1 is 2";
break;
case 3: echo "var1 is 3";
break;
default: echo "var1 is unknown";
}
?>
</body>
</html>
I know it's an old topic but still. I've just met the problem in the code I am debugging at work and maybe somebody may have similar issue...
Let's say the code looks like this:
$positions = $this->positions() || [];
You would expect (as you are used to from e.g. javascript) that when $this->positions() returns false or null, $positions is empty array. But it isn't. The value is TRUE or FALSE depends on what $this->positions() returns.
If you need to get value of $this->positions() or empty array, you have to use:
$positions = $this->positions() or [];
EDIT:
The above example doesn't work as intended but the truth is that || and or is not the same... Try this:
<?php
function returnEmpty()
{
//return "string";
//return [1];
return null;
}
$first = returnEmpty() || [];
$second = returnEmpty() or [];
$third = returnEmpty() ?: [];
var_dump($first);
var_dump($second);
var_dump($third);
echo "\n";
This is the result:
bool(false)
NULL
array(0) {
}
So, actually the third option ?: is the correct solution when you want to set returned value or empty array.
$positions = $this->positions() ?: [];
Tested with PHP 7.2.1
I don't think one is inherently better than another one, but I would suggest sticking with || because it is the default in most languages.
EDIT: As others have pointed out there is indeed a difference between the two.
There is nothing bad or better, It just depends on the precedence of operators. Since || has higher precedence than or, so || is mostly used.
Some languages use short-circuit, and others use full Boolean evaluation (if you know, this is similar to the directive $B in Pascal).
Explanations:
function A(){
...Do something..
return true;
}
function B(){
...Do something..
return true;
}
if ( A() OR B() ) { .....
In this example the function B() will never be executed. Since the function A() returns TRUE, the result of the OR statement is known from the first part without it being necessary to evaluate the second part of the expression.
However with ( A() || B() ), the second part is always evaluated regardless of the value of the first.
For optimized programming, you should always use OR which is faster (except for the case when the first part returns false and second part actually needs to be evaluated).