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
Related
I'm trying on PHP 7.4
<?php
function test(){
do{
$val=(int)readline("Insert a number in the range of 1-5 :");
print_r(($val>5 || $val!==0)."\n");
}while ($val>5 || $val!==0);
}
test();
But it just doesn't work as expected. It just leaves the loop when I insert 0, but not when I insert a number less than or equal to 5.
This condition is incorrect for what you're trying to do.
while ($val>5 || $val!==0)
None of the numbers you want to cause the loop to end are equal to zero, so the $val!==0 part of the condition will always be true unless $val is zero.
If either part of an or expression like $val>5 || $val!==0 is true, then the entire expression is true.
You need this instead:
while ($val > 5 || $val < 1)
I'm trying to get the if statement to echo equals true but it equals false. What am I doing wrong?
sometimes $line-2 will be 5% and sometimes it will be 0%. So it varies like that. How would I write the if statement for both cases?
So basically, I want it to echo equal true if the variable line_2 is 0% or is 5%. I only want it to echo equals false if the variable is anything other than 0% or 5%.
$line_2 = '5%'; // this will be random. Can be 0%. Can be 5%. Can be 25%.
if (strpos($line_2, '5') === false || strpos($line_2, '0') === false) {
echo 'equals false';
} else {
echo 'equals true';
}
more clarification.
Where it says echo 'equals false' there is actually a command there to execute another php script. I need that script to be executed only if line_2 does not equal 5% or it does not equal 0%.
Hope that sums it up.
Your problem stems from a misunderstanding of the way you negate conditional statements.
You mention that you want to echo true if $line_2 contains a 0 OR a 5; however, your if statement checks the opposite condition to echo false and will echo true if the condition fails. So we need to change the condition from if line contains 0 or line contains 5 to if not (line contains 0 or line contains 5).
The way you accomplish this is by considering De Morgan's laws. Specifically, when you distribute negation across logical OR or logical AND, the following holds true:
not (A OR B) = (not A) AND (not B)
not (A AND B) = (not A) OR (not B)
That is, you distribute the negation and change the logical operator to its opposite.
In this case, since you want to accomplish not (line contains 0 or line contains 5), you should distribute it such that you obtain (not line contains 0) and (not line contains 5), which looks like this:
$line_2 = '5%'; // this will be random. Can be 0%. Can be 5%. Can be 25%.
if (strpos($line_2, '5') === false && strpos($line_2, '0') === false) {
echo 'equals false';
} else {
echo 'equals true';
}
The problem with your current code is that you instead have a solution resembling if (not line contains 0) or (not line contains 5). The difference between the two is only in the logical operator connecting the two conditions, where you're using or but should really be using and.
Based on OP's edit, you should reverse your if condition check logic. Do the following:
$line_2 = '5%'; // Or it can be 0%
if (strpos($line_2, '5') !== false || strpos($line_2, '0') !== false) {
echo 'equals true'; // 0 or 5 is found in the string
} else {
echo 'equals false';
}
You don't really need strpos() for this unless $line_2 might sometimes contain more strings.
<?php
$line_2 = '5%';
$statement = 'equals false'; //Set the default message
if ($line_2 === '5%' || $line_2 === '%0') { //Check if $line_2 equals 5% or 2%. Note the strong comparison since $line_2 is a string.
$statement = 'equals true';
}
echo $statement;
Use && instead
Using the OR operator in that if statement will return true if that character is '5' OR '0'
So, becausestrpos($line_2, '0') === false will return true, your statement will become
if(false || true)
thus echoing 'equals false', whereas using AND
if(false && true)
will be false, giving you 'equals true'
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");
}
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
Can someone please explain in detail what these if statements are doing?
What does the three === signs to in the first one, and What does the single & in the second mean?
$aProfile = getProfileInfo($iId);
if($aProfile === false)
return false;
if(!((int)$aProfile['Role'] & $iRole))
return false;
=== tests for type-safe equality.
'3' == 3 will return true, but '3' === 3 will not, because one's a string and one's an integer. Similarly, null == 0 will return true, but null === 0 will not; 10.00 == 10 will return true, but 10.00 === 10 will not.
& is the bitwise AND operator. It returns a bitmask in which a bit is set if both the corresponding bits are set from the original two bitmasks.
For example:
$x = 5;
$y = 17;
echo $x & $y;
causes 1 to be echoed. $x is ...000101, $y is ...010001. The only bit that is set in both of them is the rightmost one, so you get ...000001, which is 1.
Here's a good guide to PHP operators:
http://www.tuxradar.com/practicalphp/3/12/3
See the section on bitwise operators for info on the &.