Logical Operators, || or OR? - php

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).

Related

Boolean has wrong value after operation [duplicate]

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).

Make the function return 0 and store it in a variable

Seems super trivial, but can't find a solution to this specific case on SO
A function may return a value of 0 OR another number, which I then want to store in a variable $s to calculate stuff. But can't find a clean way of doing it.
So for example:
function f() {
$v = "0";
return $v;
}
if($s = f() !== false) {
echo $s;
// ^ I want 0, but the value above is 1 (since it's true)
}
I tried returning it as a string
return "0" instead of a digit, but it doesn't work.
If I do this it will not evaluate to true so nothing will happen
if($s = f()) {
// returns nothing
}
But when I var_dump(f()), it does show string '0' (length=1)
So I can do
if(var_dump(f()) == 0)
OR
if(f() == 0)
But is there not a cleaner way to do it, so the function may return 0 or another number and I can just capture it in a variable?
Add parentheses:
if (($s = f()) !== false) {
Otherwise you're computing the value f() !== false and assigning it to $s, instead of assigning f() to $s and then comparing to false.
First
if($s = f() !== false) {
echo $s;
// ^ I want 0, but the value above is 1 (since it's true)
}
Whats happening here is return value of f() is strictly compared to false, that is, "0" is compared to false. They are not strictly equal, hence f() !== false returns true, which is stored in $s as 1.
Next,
if($s = f()) {
// returns nothing
}
This doesnt enter the if block because $s contains "0" and it is loosely equal to false.
Next
if(var_dump(f()) == 0) or if(f() == 0)
this works because it is loosely comparing "0" to 0 which is true. Hence it enters the block.
Remember, if condition does loose comparision or == and === does strict comparision. More about it here.
So, this should work in your case
if(($s = f()) !== 0)
if f() returns integers
Try some parenthesis:
if(($s = f()) !== false) {
To force $s to equal f(), not f() !== false

PHP variable declaration shorthand (similar to JavaScript)

In JavaScript, I can do this:
var somevar = {
propertyTwo : false,
propertyThree : "hello!"
}
var test = somevar.propertyOne || somevar.propertyTwo || somevar.propertyThree
alert(test); //displays "hello!"
Is there a similar functionality in PHP for this?
Haven't been able to find anything online.
I tried this, but PHP just treats it like a comparison and echo's 1 (true)
$somevar = array(
'propertyTwo' => false,
'propertyThree' => "hello!"
);
$test = $somevar['propertyOne'] || $somevar['propertyTwo'] || $somevar['propertyThree'];
echo $test; //displays '1'
Not really a big deal if there isn't, but I figured that with all of the bells and whistles provided in php 5.x, there would be some kind of shorthand for assigning the first true value in a list of values to a single variable like that.
I suppose I could write a function.
EDIT :
As I suspected, PHP doesn't have the same quirk.
Quick function I wrote
function assign_list($list){
foreach($list as $v)
if(isset($v) && $v) return $v;
return false;
}
Just pass it an array of stuff
The following will work in PHP >= 5.3, but you will still receive a Notice Error because propertyOne is not defined.
<?php
$somevar = array(
'propertyTwo' => false,
'propertyThree' => "hello!"
);
$test = $somevar['propertyOne'] ?: $somevar['propertyTwo'] ?: $somevar['propertyThree'];
echo $test; //displays 'hello!'
You could however work around this by supressing the variables, but it is highly unrecommended:
$test = #$somevar['propertyOne'] ?: #$somevar['propertyTwo'] ?: #$somevar['propertyThree'];
This doesn't work in PHP, and here's why:
$somevar['propertyOne'] = false;
$somevar['propertyTwo'] = true;
$test = $somevar['propertyOne'] || $somevar['propertyTwo'];
Imagine typing that query into an if statement:
if( $somevar['propertyOne'] || $somevar['propertyTwo'] ){ ... }
This will return true (evaluates to 1) if either variable is true.
Now, if we make all of the variables = false:
$somevar['propertyOne'] = false;
$somevar['propertyTwo'] = false;
$test = $somevar['propertyOne'] || $somevar['propertyTwo'];
The variable returns false (evaluates to 0).
Another thing we can do is:
$somevar['propertyOne'] = true;
$somevar['propertyTwo'] = true;
$test = $somevar['propertyOne'] && $somevar['propertyTwo'];
This will return true (evaluates to 1) as both variables meet the criteria.
This means that we can do things like this in PHP though:
$test = $somevar['propertyOne'] || $somevar['propertyTwo'];
if($test){ ... }
TL,DR: In PHP you are storing the result of the expression into a variable, not doing any validation on anything.

The php OR operand doesn't seem to work in a WordPress template file

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;

Difference between AND [and] &&

Given the statement:
if($value && array_key_exists($value, $array)) {
$hello['world'] = $value;
}
Would it be best to use the logical operator AND as opposed to &&?
On their own, they do exactly the same. So a && b means the same than a and b. But, they are not the same, as && has a higher precedence than and. See the docs for further information.
This example here shows the difference:
// 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) and true)
$f = false and true;
The link you provide has a note:
The reason for the two different variations of "and" and "or" operators is that they operate at different precedences. (See Operator Precedence.)
In your case, since it's the only operator, it is up to you, but they aren't exactly the same.
They are the same in conditional statements, but be careful on conditional assignments:
// The result of the expression (true && false) is assigned to $g
// Acts like: ($g = (true && false))
$g = true && false;
// The constant true is assigned to $h and then false is ignored
// Acts like: (($h = true) and false)
$h = true and false;
and
// 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;
From the Logical Operators manual you linked to.
only difference of spelling..its a good practice to use && instead of AND or and..

Categories