PHP - and / or keywords - php

Is && the same as "and", and is || the same as "or" in PHP?
I've done a few tests, and it seems they behave the same. Are there any differences?
If not, are there any other PHP signs that have word equivalents and do you think it makes the code easier to read?

and and or have higher lower precedence than && and ||. To be more exact && and || have higher precedence than assignment operator ( = ) while and and or have lower.
http://www.php.net/manual/en/language.operators.precedence.php
Usually it doesn't make a difference, but there are cases when not knowing about this difference can cause some unexpected behaviour. See examples here:
http://php.net/manual/en/language.operators.logical.php

Yes, they are logically the same. (I believe "&&" and "||" are the preferred choice in the Zend coding standards, but I can't find any specific information on this, so it might all have been a dream. Or something.)
That said:
"&&" and "||" are of a higher precedence than "AND" and "OR" (unlikely to ever be relevant, but you never know).
A lot of other languages use "&&" and "||", rather than the textual equivalents so it might be an idea to go with this.
As long as you use your choosen set of operators consistently it doesn't really matter.

What bothers me is:
echo (false and false ? true : true);
// (empty/false)
You might guess there is only the possible output of "1" (true) as there is no case which could output a false... ...but it will be "" (false).
Using && as a operator in this case satifies at least my expectations:
echo (false && false ? true : true);
// 1
So, in some cases the usage matters significantly.

The difference is on the precedence. But not only compared with each other!
In most cases you won't mind it, but there are specific cases when you have to take one step back and look at the big picture. Take this, for example:
// 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 before the "and" operation occurs
// Acts like: (($h = true) and false)
$h = true and false;
var_dump($g, $h);
This will produce, respectively:
bool(false)
bool(true)
In other words, && has higher preference than =, which has higher precedence than and, as stated in http://php.net/manual/en/language.operators.precedence.php. (It is mentioned in other answers, but I think it's worth to detail, since a misuse can lead to logical errors)
I hope it may help you. You can find more at http://php.net/manual/en/language.operators.logical.php

Related

Why do some people put the value before variable in if statement?

For example, what's different from $variable === true?
<?php
if (true === $variable) {
//
}
if (1 === intval($variable)) {
//
}
They are equivalent.
Some programmers prefer this "Yoda style" in order to avoid the risk of accidentally writing:
if ($variable = true) {
// ...
}
, which is equivalent to
$variable = true;
// ...
, when they meant to write
if ($variable === true) {
// ...
}
(whereas if (true = $variable) would generate an obvious error rather than a potentially-subtle bug).
Short answer
Some people do it in order to avoid mistakenly using the assignment operator (=) when they really meant to use a comparison operator (== or ===).
Long answer
In PHP there are 3 operators that can be mistaken for eachother:
= is the assignment operator
== is the "equal to" operator
=== is the "identical to" operator
The first operator is only used for assigning a value to a variable. The second and third are only used for comparing two values, or expressions, against eachother.
In PHP it is possible to assign a value to a variable inside control structures (if, for, while, etc.). This may cause problems if you are not careful. For example, if you want to compare $a against a boolean value you can do it like this:
if ($a == false) // or
if ($a === false)
If you are not careful, however, it may end up like this:
if ($a = false)
... which is perfectly legal code, but it is an assignment and will eventually cause problems. The reason it will cause problems is because the expression, $a=false, will be evaluated and the code will keep running as if nothing is wrong, when in fact it was not intended.
The reason some people switch around the operands, when comparing a value against a literal (fixed value, like true, false, 7, 5.2, and so on), is because it is not possible to assign a value to a literal. For example:
if (false = $a)
... will cause an error, telling the programmer that they made a mistake, which they can then fix.
I guess this is just the way of thinking in general. When you really think about a deep if statement, you think if that statement is true, not the other point of view. It's not wrong, but in my head naming it inverse, would annoy me and make me lose concentration about the statement. So I would say it's just the way people think :D.
There is no difference between ($var === true) and (true === $var). They are equivalent.
See http://php.net/manual/en/types.comparisons.php for a complete table of comparisons. You'll see that all equivalent comparisons have the same result.
Also, some people do prefer to see what's the result which is been evaluated before the statement.
Some statements might be longer and harder to read.
Ex:
if (false == (new DataParser()->makeAComplexDataParser((new SomeTransformer()->doTransformation((new someClass()->getMethodOfLongParameters($param1, $param2, (new Date()->format('Y-m-d')))))))) ) {
// do stuff
}
So it's better to think "is it false this complex expression?" instead of thinking
"this looooooooonger complex expression is....hmmmm....false?"

Processing of php 'if x && y'

I was wondering how php processes if statements.
If i were to have something such as:
if (isset($_GET['foo']) && $_GET['foo'] != $bar)
If foo isn't set, would it then drop out of the if straight away (as it is an 'and' statement so it can't succeed anyway) or would it also check the second part, rather pointlessly?
What you're describing is known as "short-circuit evaluation".
Most languages work this way, including PHP, so they will evaluate an expression until they are certain of the result, and then stop, so the remainder of the expression would not be evaluated.
As you say, this is the most efficient approach.
However, it can potentially throw a spanner in the works for inexperienced programmers, who nay try something like this:
if(doFirstProcess() && doSecondProcess() {
print "both processes succeeded";
}
In this case, the programmer is expecting both functions to be called, but if the first one returns false, then the second one will not be executed, as the program already knows enough to be certain of the final result of the expression, so it short-circuits the remainder of the expression.
There are a few languages which don't do short-circuit evaluation. VB6 was one example (back in the day). I don't know about VB.Net, but since it's evolved from VB6, I would suspect it would be similar. But aside from that, all other languages that I've worked with have used short-circuit evaluation, including PHP.
There is a section in the PHP manual about this here: http://www.php.net/manual/en/language.operators.logical.php
And you can read more on short circuit evalution here: http://en.wikipedia.org/wiki/Short-circuit_evaluation
Hope that helps.
It's known as short-circuit:
&& and and operators is executed from left to side
If left side is considered false, no reasons to check right side, so it's omitted, false returned
|| and or operators is executed from left to side too
If left side is considered true, no reasons to check right side, so it's omitted, true returned
Manual example:
// foo() will never get called as those operators are short-circuit
$a = (false && foo());
$b = (true || foo());
$c = (false and foo());
$d = (true or foo());
it will leave the if statement after the first expression evaluates to false because this statement can never be true if the first one is false and they are combinded via AND
you can check this very easily. If it wouldn't be like I said, you would get a notice that $_GET['foo'] is not defined
If the first part is false, it stops the if.
Certain operators, most notably && and || are so-called short-circuit operators, meaning that if the result of the operation is clear from the first operand (false or true, respectively), the second operand does not get evaluated.
Edit: Additionally, operands are guaranteed to be evaluated in order, this is not always true of other operators.
Will go out after the first statement.
you can test it:
will print 1:
if(1==1 && $a=1 == 1){
}
print $a;
Will not print a thing:
if(1==2 && $a=1 == 1){
}
print $a;
&& does short-circuit (i.e. returns false as soon as one condition fails).
If it doesn't, then having the isset would be pointless — it exists to prevent errors when trying to compare an undefined value to a string.
If the first check if (isset($_GET['foo']) returns false, the second part will not even be looked into anymore.

Difference between "&&" and "and" : Operator precedence and short circuiting

I was going through operator precedence section of php.net and came across this example which says
$a = 1;
$b = null;
$c = isset($a) && isset($b);
$d = ( isset($a) and isset($b) );
$e = isset($a) and isset($b);
var_dump($a, $b, $c, $d, $e);
//Result:
int(1)
NULL
bool(false)
bool(false) <== I get this
bool(true) <== I do not get this
I use quite a lot of debugging and verbose print(_r) statements in my code to keep track of where I am in the code. So I use $debug and print_r($dataArray) or $verbose and print "Updating dataArray\n" as separate statements in between the code, allowing me to control these print(_r) statements. This comes from my BASH experience where I used to write lot of [[ $condition ]] && { #Do if true } || { #Do if false }. In BASH, I knew they are short circuited and used this fact to write lot of simple one liners.
Now I am observing that lot of this practice(of writing $verbose and print) is slowly creeping into my if statements. I am aware this is NOT a recommended practice and can bite me in the back. However, I do want to master this skill as I enjoy writing such one liners and want to use it as my personal style.
So my question(s) is(are) :
Which operator (&& or and) is short circuited ?
The manual says && takes precedence over and, but can someone exemplify this by mixing the short circuited operator feature/functionality/characteristic with operator precedence. (basically mix and match of precedence and short-circuiting)
Kindly elaborate on both the short-circuiting as well as return value nature of the operators.
PS: 1. I hope associativity of these operators is same and intuitive, but if you know any quirks, please enlighten me.
PS: 2. If you still feel like warning me against the perils of such practice, kindly include examples.
EDIT : After changing my simple $var = mysql_(...) or die() code by replacing or with ||, I discovered how annoying it can be to use the || and && operators instead of and and or. The code simply didn't work ! To my understanding, the former construct assigns a return value of TRUE or FALSE to $var, which in turn make all sequential use of $var to generate warning/error/unexpected behavior. The latter construct assigns result of mysql_(...) to $var first and then evaluates the compound of = and die.
This is a good lesson for me, I better 1. Start using PDO/mysqli and handle errors on my own 2. Think twice before writing something I called above as personal style.
//note to self : don't use experience of one scripting/interpretive language while writing code in another, each one is unique and has its own quirks and pitfalls, and thats just sad *sigh*
The code
$e = isset($a) and isset($b);
is parsed the same as
($e = isset($a)) and isset($b);
Therefore $e, as determined by isset($a) and the assignment, is true - independent of evaluating isset($b).

Question with setting variables in if statements

Here is the sample:
if(($test = array('key'=>true)) && $test['key']){
// works
}
if($test = array('key'=>true) && $test['key']){
// does not work
}
Why is the parenthesis required? My understanding is that it computes the first conditional then the second no matter what.
And is it "safe" to do an assignment like this?
It's a matter of operator precedence in the language. In your second statement, you're essentially writing this to be evaluated:
$test = array('key'=>true) && $test['key'];
Just about any language is going to take that to mean this:
$test = (array('key'=>true) && $test['key']);
It's assigning to $test the value of the evaluation of the logical && between the two other values. So $test will be either true or false when evaluated.
i don't think the parens are required in PHP. they are in JS.
depends what you mean by "safe". it works. but some would argue that this is bad style and makes for less understandable and less maintainable code. otoh, K&R positively recommended it. it doesn't worry me and sometimes makes for tidier code.
It's because it's forcing the interpreter to perform the assignment before it attempts to evaluate any of conditions within the if.
Without the parenthesis, you're simply assigning the results of array('key'=>true) && $test['key'] to $test.
It is safe to use, but in this case the parenthesis are required for disambiguation. The operator precedence rules of PHP mean that the second line will be executed as:
if ($test = (array('key' => true) && $test['key'])) { .. }
So test will not be an array but a bool.
The practice of doing assignment in if statements itself is not really encouraging readability though, so you probably want to avoid doing this too much.
In PHP, the assignment operator = has lower precedence that most other operators. (For more information, see the documentation). Furthermore, the result of an expression using the assignment operator is the value of the assignment. With this in mind, consider the expressions you posted:
First example:
($test = array('key'=>true)) && $test['key']
The first part of this expression, ($test = array('key'=>true)) evaluates to array('key'=>true) (by the rule above), and the second part evaluates to true since the key was just set. Thus the whole expression evaluates to true.
Second example:
$test = array('key'=>true) && $test['key'] By the rules of operator precedence, $test is going to get assigned the value of the expression array('key'=>true) && $test['key']. The first half of this is true, but $test['key'] hasn't been set yet, so true && false is false, so $test takes the value false, which is also the result of the if condition.

What's the difference between those PHP if expressions?

What's the difference between those PHP if expressions!?
if ($var !== false)
{
// Do something!
}
if (false !== $var)
{
// Do something!
}
Some frameworks like Zend Framework uses the latest form while the traditional is the first.
Thanks in advance
The result of the expression is the same however it's a good way of protecting yourself from assigning instead of comparing (e.g writing if ($var = false) instead of if ($var == false), since you can't assign the value $var to the false keyword)
It's just a preference really. You can put it either way, a == b or b == a, but it's easier to make a mistake if you do
if ($var == false)
because if you accidentally type it with one = letter, the condition will always equal to true (because $var will be set successfully), but in case of
if (false == $var)
if you now put in =, you will get an error.
The two expressions are semantically identical. It's just a matter of preference whether to put the constant expression first or last.
There's no real difference. The operands are just on different sides but the comparison is the same nonetheless.
There is no difference. !== compares 2 expressions with type checking, and returns true if they are not equal. The difference may be in the evaluation order of the expressions, but in the case you wrote, there is no difference (and a good program must not rely on the execution order of such expressions).
Consider this scenario:
if (strpos($string, $substring)) { /* found it! */ }
If $substring is found at the exact start of $string, the value returned is 0.
Unfortunately, inside the if, this evaluates to false, so the conditional is not executed.
The correct way to handle that will be:
if (false !== strpos($string, $substring)) { /* found it! */ }
Conclusion:
false is always guaranteed to be false. Other values may not guarantee this. For example, in PHP 3, empty('0') was true, but it changed to false later on.

Categories