Double not (!!) operator in PHP - php

What does the double not operator do in PHP?
For example:
return !! $row;
What would the code above do?

It's not the "double not operator", it's the not operator applied twice. The right ! will result in a boolean, regardless of the operand. Then the left ! will negate that boolean.
This means that for any true value (numbers other than zero, non-empty strings and arrays, etc.) you will get the boolean value TRUE, and for any false value (0, 0.0, NULL, empty strings or empty arrays) you will get the boolean value FALSE.
It is functionally equivalent to a cast to boolean:
return (bool)$row;

It's the same (or almost the same - there might be some corner case) as casting to bool. If $row would cast to true, then !! $row is also true.
But if you want to achieve (bool) $row, you should probably use just that - and not some "interesting" expressions ;)

It means if $row has a truthy value, it will return true, otherwise false, converting to a boolean value.
Here is example expressions to boolean conversion from php docs.
Expression Boolean
$x = ""; FALSE
$x = null; FALSE
var $x; FALSE
$x is undefined FALSE
$x = array(); FALSE
$x = array('a', 'b'); TRUE
$x = false; FALSE
$x = true; TRUE
$x = 1; TRUE
$x = 42; TRUE
$x = 0; FALSE
$x = -1; TRUE
$x = "1"; TRUE
$x = "0"; FALSE
$x = "-1"; TRUE
$x = "php"; TRUE
$x = "true"; TRUE
$x = "false"; TRUE

"not not" is a convenient way in many languages for understanding what truth value the language assigns to the result of any expression. For example, in Python:
>>> not not []
False
>>> not not [False]
True
It can be convenient in places where you want to reduce a complex value down to something like "is there a value at all?".

Another more human, maybe simpler, way to 'read' the not not:
The first '!' does 2 things: 'convert' the value to boolean, then output its opposite. So it will give true if the value is a 'falsy' one.
The second '!' is just to output the opposite of the first.
So, basically, the input value can be anything, maybe a string, but you want a boolean output, so use the first '!'. At this point, if you want TRUE when the input value is 'falsy', then stop here and just use a single '!'; otherwise if you want TRUE when the input value is 'truthy', then add another '!'.

Lets look at
!$a;
Rather than interpreting the ! operator as as taking the
Boolean opposite of the value to its right
read
take the Boolean opposite of the expression to its right
In this case
$a;
could be an expression
so to is
!$a;
so is
!!$a;
and
!!!$a;
and so on, as each of these is a valid expression, the ! operator can be prepended to each of them.

Related

Can you conditionally negate a function in PHP?

For example
$x = true;
return (($x ? "!" : "" ). is_null(NULL));
This obviously doesn't work, is there a way to do it?
The goal is to refactor this
$var == true
? array_filter($labels, function($v){return str_contains($v, 'return');})
: array_filter($labels, function($v){return !str_contains($v, 'return');});
Thanks
A common way of describing boolean combinations is as a truth table listing the possible inputs and outputs. In this case:
$x
is_null($var)
Desired result
false
false
false
false
true
true
true
false
true
true
true
false
So, the result you want is "either $x is true, or is_null($var) is true, but not both".
Looking in the PHP manual under "logical operators", we see that that's the definition of the xor operator, so you could write this:
return $x xor is_null($var);
An intermediate variable and simple if statement as shown in Justinas's answer is probably a lot more readable, though. Readability is extremely important in programming, because code is read far more times than it's written.
You can, but with different approach: first execute function and then check if it needs to be inverted
$result = is_null($var);
if ($x) {
// invert result from e.g. true to false
$result = !$result;
}
is_null returns a boolean. $x is a boolean. Compare both booleans:
return is_null($var) != $x;

PHP check if a variable is empty or not

In my case, the variables $nr and $str can have only two possible values. $nr can contain integer/numeric or null, not "null" between double quotes. $str can contain a string value or null. Can I just check if the variables are empty or not like this?
if ($nr) {}
if (! $nr) { return; }
if ($str) {}
if (! $str) { return; }
I think the answer is Yes but some code snippets of others made me doubt about that because they check it as following.
if (empty($var) || "" === $var || null === $var) { return; }}
I think this is unnecessary. To be specific, it is in PHP7.4.
You can check https://www.php.net/manual/en/types.comparisons.php to see what can be used to check if something is truthy or falsy. Below is the table of the link before condensed into a table of things you can plug into an if statement and what the results will be.
Before utilizing these tables, it's important to understand types and their meanings. For example, "42" is a string while 42 is an int. false is a bool while "false" is a string.
Expression
bool : if($x)
$x = "";
false
$x = null;
false
var $x;
false
$x is undefined
false
$x = array();
false
$x = array('a', 'b');
true
$x = false;
false
$x = true;
true
$x = 1;
true
$x = 42;
true
$x = 0;
false
$x = -1;
true
$x = "1";
true
$x = "0";
false
$x = "-1";
true
$x = "php";
true
$x = "true";
true
$x = "false";
true
if ($var)/if (!$var) simply check for truthy/falsey values respectively (they're complimentary opposites, which one you choose is merely a question of which makes more sense in your flow). Falsey values in PHP are:
false
null
0, -0, 0.0, -0.0
"0" (0 as a string)
"" (empty string)
array() (empty array)
empty SimpleXML objects (interesting special case; thanks Obama! 🤔)
Everything else is truthy.
So, if none of your desired values fall into this list and all of your undesired values are in this list, then a simple if ($var)/if (!$var) will do just fine. If your desired/undesired list does not happen to align with this and you want some of column A but also some of column B, then you need to do more specific and complicated checks.
The only time you'll want to use emtpy is if the variable you're checking may legitimately not exist. empty($var) is just !$var, but doesn't raise an error if $var doesn't exist at all. That's its only purpose, and you do not want to suppress error reporting unless you have to. In a properly written program where you declare your variables properly, there should be very very little use for empty, since you should know what variables exist and which don't.

PDO fetchAll returns number 1 without any rows [duplicate]

What does the double not operator do in PHP?
For example:
return !! $row;
What would the code above do?
It's not the "double not operator", it's the not operator applied twice. The right ! will result in a boolean, regardless of the operand. Then the left ! will negate that boolean.
This means that for any true value (numbers other than zero, non-empty strings and arrays, etc.) you will get the boolean value TRUE, and for any false value (0, 0.0, NULL, empty strings or empty arrays) you will get the boolean value FALSE.
It is functionally equivalent to a cast to boolean:
return (bool)$row;
It's the same (or almost the same - there might be some corner case) as casting to bool. If $row would cast to true, then !! $row is also true.
But if you want to achieve (bool) $row, you should probably use just that - and not some "interesting" expressions ;)
It means if $row has a truthy value, it will return true, otherwise false, converting to a boolean value.
Here is example expressions to boolean conversion from php docs.
Expression Boolean
$x = ""; FALSE
$x = null; FALSE
var $x; FALSE
$x is undefined FALSE
$x = array(); FALSE
$x = array('a', 'b'); TRUE
$x = false; FALSE
$x = true; TRUE
$x = 1; TRUE
$x = 42; TRUE
$x = 0; FALSE
$x = -1; TRUE
$x = "1"; TRUE
$x = "0"; FALSE
$x = "-1"; TRUE
$x = "php"; TRUE
$x = "true"; TRUE
$x = "false"; TRUE
"not not" is a convenient way in many languages for understanding what truth value the language assigns to the result of any expression. For example, in Python:
>>> not not []
False
>>> not not [False]
True
It can be convenient in places where you want to reduce a complex value down to something like "is there a value at all?".
Another more human, maybe simpler, way to 'read' the not not:
The first '!' does 2 things: 'convert' the value to boolean, then output its opposite. So it will give true if the value is a 'falsy' one.
The second '!' is just to output the opposite of the first.
So, basically, the input value can be anything, maybe a string, but you want a boolean output, so use the first '!'. At this point, if you want TRUE when the input value is 'falsy', then stop here and just use a single '!'; otherwise if you want TRUE when the input value is 'truthy', then add another '!'.
Lets look at
!$a;
Rather than interpreting the ! operator as as taking the
Boolean opposite of the value to its right
read
take the Boolean opposite of the expression to its right
In this case
$a;
could be an expression
so to is
!$a;
so is
!!$a;
and
!!!$a;
and so on, as each of these is a valid expression, the ! operator can be prepended to each of them.

how ordering makes a difference within an expression for an if statement

I have an array ...
$a= array(1,2,3,4);
if (expr)
{ echo "if";
}
else
{ echo 'else';
}
When expr is ( $a = '' || $a == 'false') , output is "if" ,
but when expr is ( $a == 'false' || $a = '' ) , output is "else"
Can anyone explain why & how ordering makes a difference ??
Edit : I understand that I am assigning '' to $a. That is not the problem. The real question is : What does the expression $a = '' return? And why does reversing the order of the 2 situations switch us from the IF section to the ELSE section?
AGAIN : I UNDERSTAND I AM ASSIGNING NOT COMPARING. PLEASE ANSWER THE QUESTION AS IS.
First, never use = as a comparison operator. It is an assignment operator.
The difference is that false (as a boolean) is not the same as 'false' as a string.
Certain expressions are type juggled by PHP to evaluate somewhat differently to how you would expect.
false==""
// TRUE.
false=="false"
// FALSE.
Additionally, when you try to compare numbers to strings, PHP will try to juggle the data so that a comparison will be performed. There is a lot to it (much more than I will post here) but you would do well to investigate type juggling and various operators. The docs are a great start for this. You should also have a read of the comparison operators which go into a lot of detail about how various comparisons will work (depending on whether you use == or === for example).
With $a = '' you are setting $a to an empty string. This is the same as:
$a = '';
if($a){
echo 'if';
}
The || operator checks if the first condition is true and if it is, it continues with the code in the brackets. In PHP, if $a is set to anything, it will return true. In the second case $a does not equal the string 'false' (you are not comparing it to a boolean false even!), so it executes the code in the else part.
And Fluffeh is not entirely correct. You can use the assignment operator in an if condition very effectively, you just have to be smart about it.
$a = '' is an assignment: you have, in error, used = in place of ==. Assignment is an expression which has the value of the thing your assigning.
A single equals sign = is the assignment opporator, so $a = '' is assigning an empty string to $a not checking if it is equal to.
In your 1st example you set the value of $a to an empty string, then check if it is false. An empty tring evalutes to false in php, so the conditional is true.
In your second example, you check if $a equals false 1st (when the value of $a is an array), so the conditional is false

Short-circuit evaluation via the AND operator in PHP

I'm trying to improve my coding ninja h4x skills, and I'm currently looking at different frameworks, and I have found sample code that's pretty hard to google.
I am looking at the FUEL framework used in a project.
The sample I don't understand is
$data and $this->template->set_global($data);
What is the and keyword doing in this line of code? It is used many places in the framework and it's the first that I have found that uses it.
This is a type of "short circuit evaluation". The and/&& implies that both sides of the comparison must evaluate to TRUE.
The item on the left of the and/&& is evaluated to TRUE/FALSE and if TRUE, the item on the right is executed and evaluated. If the left item is FALSE, execution halts and the right side isn't evaluated.
$data = FALSE;
// $this->template->set_global($data) doesn't get evaluated!
$data and $this->template->set_global($data);
$data = TRUE;
// $this->template->set_global($data) gets evaluated
$data and $this->template->set_global($data);
Note these don't have to be actual boolean TRUE/FALSE, but can also be truthy/falsy values according to PHP's evaluation rules. See the PHP boolean docs for more info on evaluation rules.
When you use logical operators, operands (the value on the left and the value on the right) are evaluated as boolean, so basically that code will do this, in a shorter way:
$o1 = (Bool)$data; // cast to bool
if($o1)
$o2 = (Bool)$this->template->set_global($data); // cast to bool
Edit:
Some additional information:
$a = 33;
isset($a) && print($a) || print("not set");
echo "<br>";
isset($a) AND print($a) OR print("not set");
echo "<br>";
Try to comment/decomment $a = 33;. This is the difference between && and AND, and between || and OR (print returns true that is casted to "1" when converted to string).
It is a valid statement and works like this:
If $data is valid (is not '', 0 or NULL) then run $this->template->set_global($data)
It's a quick way of saying:
if ($data)
{
$this->template->set_global($data);
}
Btw you can also use && instead of and
PHP supports both && and and for the logical AND operation, and they generally work identically, except and has a slightly lower operator precedence than &&: http://php.net/manual/en/language.operators.precedence.php
It's a boolean operator which means it takes two operands and returns a boolean value-- true or false. If both operands evaluate to true (anything but and empty string, zero or null in PHP) it will return true, otherwise the result will be false.
Here's PHP's official docs on the and operator: http://www.php.net/manual/en/language.operators.logical.php
<?php
$a = true and false; # FALSE
$b = true and 5; # TRUE
$c = '' and 0; # FALSE
$d = null and true; # FALSE
?>

Categories