php AND, OR operators in If statements - php

I am new to programming so please don't judge me. This question is simple concept knowledge that I have somehow missed. My question is, do brackets make difference when you are using AND and OR operators? For example,
if ( x == 1 && ( y == 1 || y == 2 ) ){
// do something
}
Basically, what I want to do is that x has to take value 1 at all times and y can vary between 1 and 2. Does the above code make sense for this purpose? And is it different from:
if ( x == 1 && y == 1 || y == 2 ){
// do something
}

Yes, they do. What you're really asking is what is the operator precedence for && and ||?
&& has higher precedence than ||, which means it will be evaluated first if the order isn't specified explicitly using brackets (as you do in your first example).
You can think of precedence as the order in which PHP adds brackets to the expression if you haven't already put them in. In your second example, the operator with the highest precedence is ==, so all instances of these are grouped with brackets:
(x == 1) && (y == 1) || (y == 2)
The next highest is &&, so now we add brackets around these:
((x == 1) && (y == 1)) || (y == 2)
The expression is now unambiguous, so we needn't add any more brackets.
Hopefully it's clear from this argument that the first expression in your post is not the same as the second. For example, if x==0 and y==2, the first expression (correctly) evaluates to false, while the second evaluates to true.
See here for a list of operator precedences in PHP.

Yes,
in the first code,‍‍ ‍‍‍‍‍x == 1‍ will be checked first and the result will be checked against the result of y == 1 || y == 2 .
and in the second one , x == 1 && y == 1 will be checked at first and the result of it will be checked against || y == 2

&& has higher precedence than ||, so it'll be evaluated first. The use of parentheses helps you make sure the order of execution is same as what you expect.
From the PHP manual:
Use of parentheses, even when not strictly necessary, can often increase readability of the code by making grouping explicit rather than relying on the implicit operator precedence and associativity.

The && (logical AND) operator indicates whether both operands are true.
The || (logical OR) operator indicates at least one of the operands are true. And...what an operand is?
when you use a simple expression, like x == 1, that is considered an operand.
if you use brackets, everything inside the brackets is consider one operand, no matter how complex it is inside. So you can group conditions.
so x == 1 && ( y == 1 || y == 2 ) will evaluate if the first operand x == 1 is true, and the second operand, the whole ( y == 1 || y == 2 ) is true.
To know if something inside brackets is true or false, whatever it has inside is evaluated as an independent expression.
so, we have to operands. First, it will check if x == 1 is true. If it is false, it wont check what is inside the brackets, it doesnt matter since anyways the first condition is not fulfilled. if x==1, we can check the second operand:
so it will check the expresions inside the brackets, this is, y == 1 || y == 2, and if some is true, then ( y == 1 || y == 2 ) is true operand, and the whole expression will be x == 1 && true, so basicaly it now depends on x, and if none inside the brackets is true, then ( y == 1 || y == 2 ) is a false operand, and the whole operation will be x == 1 && false so everything is false
If you dont use brackets, you can achieve the same results, but you will have to check the precedence rules, that will be harder to keep in mind at the begining
I recommend that before you learn a programing language, you read a few tutorials about boolean algebra and logic. Everything will be easier after that.

in first example
the left side is evaluated first. if that is true it looks to the right side which is the bracket so it goes to the bracket and evaluates it and than checks against left side.
the second example will not work as you want because if x!=1 it will still go to right side to look for y==1 and you can end up with true.

Brackets don't make a difference. If you want to read more about it, look at the wikipedia page of Boolean logic:
http://en.wikipedia.org/wiki/Boolean_algebra

Related

Why does this conditional statement not work?

I have this function in PHP to check if a number is 1 or 0, and if it isn't to die no access. This is for a lightweight security system implemented in one of my games to help prevent most cheating.
$number = 1;
if ($number<>0 || $number<>1){
die("nope");
}
However, when I run this code above, nope is echoed. Why?
The <> comparison operator is the same as != (not equal). The || is an OR comparison operator. In the conditional statement above if either expression is not true, the code block will execute. since 1 != 0, the code block will execute.
You are checking if $number is greater/less than 0 OR greater/less than 1. Since 1 is greater than 0 the first condition is true and the statement is true. So you get the message 'nope'.
Change it to this:
if ($number <> 0 && $number <> 1){
Your code always pass, it checks if $number is NOT one or is NOT zero - try proper solution:
$number=1;
if (!($number==0 || $number==1)){
die("nope");
}
your first condition $number<>0 is true. <> means not equal to(!=). 1 != 0 is true.
so it is always inside if condition.
Your condition $number<>0 || $number<>1 will be true when $number is 1 because 1 is not equal to 0. Since you are using ||, it will short-circuit since true || <anything> is true.
You want to use && here instead. To check whether $number is not equal to either 0 or 1.
$number=1;
if ($number<>0 && $number<>1){
die("nope");
}
Following De Morgan's laws, you can also do:
$number=1;
if (!($number==0 || $number==1)){
die("nope");
}

PHP order of logical operators

I'm curious about how PHP handles conditional statements / order of operations with nesting. If I use the following if condition:
if(x == (1 || 2))
{
// do something
}
I would expect it to behave the same as
if(x == 1 || x == 2)
{
// do something
}
...but it doesn't. My first example seems like it would be a handy shorthand that makes pretty good sense, but it doesn't do what I expect. Can anyone shed some light on the issue? What exactly does PHP do with my first statement?
So for this piece of code:
if ($x == ( 1 || 2))
{
// do something
}
In PHP, any non-zero number is considered true. Disclaimer: This fact isn't necessarily true in other languages. So in PHP, 0 is the only number considered false. So you're asking if $x == true in the above piece of code.
Hence, whenever $x is any number other than 0 the statement inside the if will resolve as true. However, when $x = 0 then that is equivalent to saying false == true which of course will resolve as false.
This article might help: PHP: Booleans
Your shorthand is logically invalid. In almost every case you'll have to write out the full logical cases for all possibilities you want to test for.
I say 'almost' because in PHP you can do something ridiculous like:
if( in_array($x, array(1,2)) ) {
// code!
}
x == (1 || 2)
evaluates like this:
(1 (if its false) then testing for 2, if not, the expression returns true)
now it will become:
if(x==true)?
Another example taken from (PHP.NET):
// foo() will never get called as those operators are short-circuit
$b = (true || foo());
See here about the precedence of an operator
http://php.net/manual/en/language.operators.precedence.php
It will behave the same as math (think BEDMAS), with the brackets being executed first. So your example is behaving as:
if (x == ( 1 || 2)) {
//code
}
and because 1 and 2 are both non-zero values (thus both true), you get:
if (x == true) {
//code
}
Unfortunately to get what you want you'll need:
if (x == 1 || x == 2) {
//code
}
how would it make sense? you are asking the computer to execute the following logical expression:
if x == (1 || 2) which is same as x == (the result of 1 || 2)
so your expression would be x == true since 1 || 2 would return true
computers do whatever you tell them to do
if(x == (1 || 2))
{
// do something
}
OR and AND operations come back with TRUE or FALSE
you statement says - if x equals (true) - as 1 or 2 will always be true
- this just doesn't make sense...
In first if evaluate result of 1||2 and check that it equal to x
In second its like this or this or this
however in first you can see that var_dump(1 || 2) returns every time true so
$x = 3;
var_dump($x == 1 || 2);
if($x == 1 || 2){
echo 'inside if';
}
is also true so it will print inside if even $x is 3
so imo second way is way to go

Multiple OR in php if() not seeming to respond properly. Tested array values and all. What am I doing wrong?

I am running a very simple if statement which works perfect until I add the two additional || (or) operators.
Here is my code:
if ($planDetails['Company']['name'] != 'company1'
|| $planDetails['PlanDetail']['name'] != 'pd-name1'
|| $planDetails['PlanDetail']['name'] != 'pd-name2') { echo "TEST"; }
I've checked my array data and table values to ensure they are precise in the names etc.. And this is not kicking. What am I doing wrong? When I remove the additional 2 || options, the first argument works fine, so I know my logic is correct.
What in the name am I doing wrong here. Someone please set me straight!
Well, what I read here is:
If $variable is not equal to A Or $variable is not equal to B
Then echo "TEST"
Since $variable cannot be equal to both A and B at the same time, it will always print "TEST".
Of course, the above refers to the last two conditions in your if.
Your ors should be ands. The expression a != 1 || a != 2 is always true because whatever the value of a is, one or the other of the expressions will be true, so the final result will be true.
To fix, change || to &&.
I guess you made this mistake because you started with this expression and wanted to invert it:
if ($planDetails['Company']['name'] == 'company1'
|| $planDetails['PlanDetail']['name'] == 'pd-name1'
|| $planDetails['PlanDetail']['name'] == 'pd-name2')
The simplest way to invert this expressions is as follows:
if (!($planDetails['Company']['name'] == 'company1'
|| $planDetails['PlanDetail']['name'] == 'pd-name1'
|| $planDetails['PlanDetail']['name'] == 'pd-name2'))
Using this method, you don't need to do any complex boolean logic in your head to see that it works - it's just a simple negation of what you already know. Note that this is not the same as inverting the == to != individually. See De Morgan's Laws for more details.
Please refer to De Morgan's laws.
NOT (P AND Q) = (NOT P) OR (NOT Q)
NOT (P OR Q) = (NOT P) AND (NOT Q)
You have:
(NOT P) OR (NOT Q) OR (NOT R)
Which is the same as:
NOT (P AND Q) OR (NOT R) =>
NOT (P AND Q AND R)
Therefore, P, Q, R must all be false to print "TEST". If one of them is true then you will not print "TEST".
I believe you want:
NOT (P OR Q OR R)
Which would be:
(NOT P) AND (NOT Q) AND (NOT R)
OR
if (!($planDetails['Company']['name'] == 'company1'
|| $planDetails['PlanDetail']['name'] == 'pd-name1'
|| $planDetails['PlanDetail']['name'] == 'pd-name2'))
{
echo "TEST";
}
AKA
if ($planDetails['Company']['name'] != 'company1'
&& $planDetails['PlanDetail']['name'] != 'pd-name1'
&& $planDetails['PlanDetail']['name'] != 'pd-name2')
{
echo "TEST";
}

Difference between & and && in PHP

I am confused with & and &&. I have two PHP books. One says that they are same, but the another says they are different. I thought they are same as well.
Aren't they same?
& is bitwise AND. See Bitwise Operators. Assuming you do 14 & 7:
14 = 1110
7 = 0111
---------
14 & 7 = 0110 = 6
&& is logical AND. See Logical Operators. Consider this truth table:
$a $b $a && $b
false false false
false true false
true false false
true true true
The other answers are correct, but incomplete. A key feature of logical AND is that it short-circuits, meaning the second operand is only evaluated if necessary. The PHP manual gives the following example to illustrate:
$a = (false && foo());
foo will never be called, since the result is known after evaluating false. On the other hand with
$a = (false & foo());
foo will be called (also, the result is 0 rather than false).
Matthew's answer about how Logical And && operator is the biggest difference; logical comparison will stop when it will find something that breaks the chain. In addition, one more big difference it the result type/value.
tl;dr
By using the Logical And &&, it will always return a Boolean type/value, true or false.
false & 1 // int(0)
false && 1 // bool(false)
It is important to use Boolean type/values when returning a function with a logical result, because someone can use the Identical comparison operator === to compare the results (which is high likely to happen) and it will fail if you use something like this:
(false & 1) === false // bool(false)
(true & true) === true // bool(false)
Never use Bitwise And & when you need to make a logical comparison and especially when returning values from functions with logical results. Instead use the Logical And &&:
(false && 1) === false // bool(true)
(true && true) === true // bool(true)
When comparing characters, Logical And && will always result to true, even with NUL character, unless if it's converted to an integer:
'A' && 'B' // bool(true)
'A' && 0 // bool(false)
'A' && '\0' // bool(true)
'A' && (int)'\0' // bool(false)
If you use the Bitwise And & with characters, it will result the character corresponding to the Bitwise And operation between those two characters:
'A' & 'B' // string(1) "#"
01000001 // ASCII 'A'
&
01000010 // ASCII 'B'
=
01000000 // ASCII '#'
Beware the usage of the Bitwise And & when using with types other than Integers and Characters (which are special kind of integers). For example, if you use it with real numbers float/double, then it can result to 0 even if both operands are NOT 0:
1.0 & 1.0 // int(1)
2.0 & 1.0 // int(0)
1.0 && 1.0 // bool(true)
2.0 && 1.0 // bool(true)
In addition, if we go at assembly instructions level, we can see that difference and how the compiler manages to handle so the Logical And && uses cmp <var>, 0 to compare and does not continue executing if one operand fails; Bitwise And uses and <var1>, <var2> to make a bitwise result and then test if it's of 0 value. I know this question is tagged for php and php behavior may be different than c, but I'll use a small c program to demonstrate how compiler behaves when using Logical and Bitwise And.
Let's assume we have a program in c that uses both Bitwise and Logical And:
int a = 0;
int b = 1;
int c = 2;
if (a & b)
c = 3;
if (a && b)
c = 4;
The compiler will generate the following assembly opcodes (W32Dasm result for x86; I have changed the memory addresses with <variable> names for simplicity and to be more understandable):
:0229 mov <a>, 0
:0230 mov <b>, 1
:0237 mov <c>, 2
// if (a & b) begins
:023E mov eax, <a>
:0241 and eax, <b> // a bitwise and b, result stored to eax
:0244 test eax, eax // test eax and set ZeroFlag if equals to 0
:0246 je 024F // >--- Jump if ZeroFlag is set
:0248 mov <c>, 3 // | or set c = 3
// if (a && b) begins |
:024F cmp <a>, 0 // <--- compare a to 0 and sets ZeroFlag if difference is 0
:0253 je 0262 // >--- Jump if ZeroFlag is set (a == 0)
:0255 cmp <b>, 0 // | compare b to 0 and sets ZeroFlag if differemce is 0
:0259 je 0262 // | >--- Jump if ZeroFlag is set (b == 0)
:025B mov <c>, 4 // | | or set c = 4
:0262 <program continues> // <--- <---
The compiler not only uses different instructions to compare between the Logical and Bitwaise And, but at the line :0253 in if (a && b) logical comparison, we see that if a == 0 then it jumps and does not check for the rest operands.
So, I disagree to animuson's comment:
They are both the same thing, they're just used for two different
things to accomplish the same task. – animuson Mar 4 '10 at 1:42
They are not the same thing and both are/(should be) used for specific tasks depending on the programs' logic/flow.
AND operation:
& -> will do the bitwise AND operation , it just doing operation based on
the bit values.
&& -> It will do logical AND operation. It is just the check the values is
true or false. Based on the boolean value , it will evaluation the
expression
As the others are saying, a single & is bit-wise. It basically converts the left-hand value into its bits representation, and the right hand side into bits representation as well, then performs logical AND between them and outputs the result.
Double && is either true or false, (in some languages 0 or 1) if both left and right side are true (or non-zero).
I'd also add that this is not just in PHP. It is like that in many many other languages as well, like C, Java, Ruby, etc.
&& is & performed on operands reduced to either 1 or 0.
(In other words, && is a bitwise operator under the caveat that it changes its operands. That is, logical operations are a subset of bitwise operations.)

What is the difference between the | and || operators?

| and || - what is the difference between these two operators in PHP?
| is a bitwise or, || is a boolean or.
Meaning
| is binary operator, it will binary OR the bits of both the lefthand and righthand values.
|| is a boolean operator, it will short circuit when it encounters 'true' (any non-zero value, this includes non-empty arrays).
Examples
print_r(1 | 2) // 3
print_r(1 || 2) // 1
When used with functions:
function numberOf($val) {
echo "$val, ";
return $val;
}
echo numberOf(1) | numberOf(2); // Will print 1, 2, 3
echo numberOf(1) || numberOf(2); // Will print 1, 1
Just like the & and && operator, the double Operator is a "short-circuit" operator.
For example:
if(condition1 || condition2 || condition3)
If condition1 is true, condition 2 and 3 will NOT be checked.
if(condition1 | condition2 | condition3)
This will check conditions 2 and 3, even if 1 is already true. As your conditions can be quite expensive functions, you can get a good
performance boost by using them.
There is one big caveat, NullReferences or similar problems. For example:
if(class != null && class.someVar < 20)
If class is null, the if-statement will stop after "class != null" is false. If you only use &, it will try to check class.someVar and you get a
nice NullReferenceException. With the Or-Operator that may not be that much of a trap as it's unlikely that you trigger something bad,
but it's something to keep in mind.
No one ever uses the single & or | operators though, unless you have a design where each condition is a function that HAS the be
executed. Sounds like a design smell, but sometimes (rarely) it's a clean way to do stuff. The & operator does "run these 3 functions,
and if one of them returns false, execute the else block", while the | does "only run the else block if none return false" - can be useful,
but as said, often it's a design smell.
| operates on the bits of a variable: 2 | 4 = 6
|| operates on The Boolean value of a variable: 2 || 4 = TRUE
| -> binary operator || -> Boolean operator or -> also a Boolean
operator with lower precedence
$x = false | true; //will set $x to an integer
$x = false || true; //will set $x to true
$x = false or true; //will set $x to false exactly the same that:
($x = false) || true;

Categories