In the PHP below if I compare a variable using == it works as I would expect it to, if I use != then my code breaks, can someone explain or help?
$_GET['p'] = 'home';
// DOES NOT work, it will always return "show JS" regardless to what string I have
if ($_GET['p'] != 'home' || $_GET['p'] != 'create.account'){
echo 'show JS';
}else{
echo 'do not show JS';
}
// Works as I would expect it to
if ($_GET['p'] == 'home' || $_GET['p'] == 'create.account'){
echo 'do not show JS';
}else{
echo 'show JS';
}
$_GET['p'] can't be two different things at the same time. You say int the first expression;
p not home or not create.account. Its always true. You should use && instead of ||
You can see the problem by DeMorgans Laws for negation
!( A || B ) === (!A && !B)
The solution you give is impossible because there is no way for both statements to be false, because that would imply the string is equivalent to both the compared strings. The only way the else block would be hit is if both were false (because of the OR statement).
(X != A) || (X != B)
≡ !(X == A) || !(X == B)
≡ !((X == A) && (X == B))
(X == A) && (X == B) is always false since the condition A != B but X cannot be both A and B at the same time. So !((X == A) && (X == B)) and your (X != A) || (X != B) is always true.
if ($_GET['p'] != 'home' && $_GET['p'] != 'create.account')
Related
I have a question about IF statements with multiple logical OR operators.
If we let:
$x=1;
A. I typical would write a IF statement comparing two items like this:
if($x == 1 || $x == 2) echo 'good';
else echo 'bad';
B. But, is this a valid IF statement? If not, why? (because it seems to work)
if($x == (1 || 2)) echo 'good';
else echo 'bad';
C. I typical would write a third comparison like this:
if($x == 1 || $x == 2 || $x == 3) echo 'good';
else echo 'bad';
D. What about this, following suit with B, above? (it does not seem to work)
if($x == (1 || 2 || 3)) echo 'good';
else echo 'bad';
The example in B, above works, but not the example in D. Why?
I cannot find any PHP documentation as to why.
Here is what happens for every version:
A. $x == 1 || $x == 2
PHP will compare $x with the value 1, this is true so it can short-circuit the if and echo 'good'.
B. $x == (1 || 2)
PHP will evaluate 1 || 2 because parentheses indicate the priority, as the result should be a boolean expression it will cast 1 to a boolean which evaluates to true so the expression becomes $x == true.
Now PHP will evaluate this expression. First it will cast both types to the same, according to the documentation, it will "Convert both sides to bool". So, same as above, as $x is 1 it will be cast to true and then the expression becomes true == true which is true.
C. $x == 1 || $x == 2 || $x == 3
It is the same as A.
D. $x == (1 || 2 || 3)
It is quite the same as B.
And, for the record 1 == (1 || 2 || 3) evaluates to true.
I am trying to consolidate a few different if statements. What I am trying to accomplish would read something like this:
If (this is true and this is true) OR (this is true and this is true) AND (This is true)
So, one at least one of the first two sets of parentheses would need to be true, and if one of those is true, then also the last set of parentheses would need to be true, in order for the code inside to be executed.
Here is the specific code I am (unsuccessfully) trying to make work:
if(($calc->number % 2 == 1 && $calc->doubleColor == 'b2' | $calc->number % 2 == 0 && $calc->doubleColor = 'r2') && in_array($calc->number, $backToBet)){
}
Is there a way to do this? A possibility? Is there any drawback to getting a lot into a single if statement?
EDIT
$blackMatch = $calc->number % 2 == 1 && $calc->doubleColor == 'b2';
$redMatch = $calc->number % 2 == 0 && $calc->doubleColor = 'r2';
$numberMatch = in_array($calc->number, $backToBet);
if(($blackMatch || $redMatch) && $numberMatch){
}
/ ** Calc->number = 2, $blackMatch = false, $redMatch = false,
$numberMatch array contains 2 **/
Basically what I end with is a 'true' result, even though neither of the conditions within the inner parentheses are satisfied.
to make code easier to read, I'd suggest to use separate variables, like this:
$condition1 = ($calc->number % 2 == 1) && ($calc->doubleColor == 'b2');
$condition2 = ($calc->number % 2 == 0) && ($calc->doubleColor == 'r2');
$condition3 = in_array($calc->number, $backToBet);
if (($condition1 || $condition2) && $condition3) {
}
two things to note:
|| is logical OR, | is bitwise OR
== is comparison, = is assignment
I am trying to make a statement with multiple ANDS and ORS, is this possible?
This is what i currently have:
elseif ($a == 'promo' && strstr(ucwords($promo_name),'30% Off') && $b == 'yes')
{echo 'this is a 30% off promotion'; }
I am looking to echo the same message if the $promo_name has either '30% Off' OR 'Save 30%'.
Would I be correct with this?
elseif ($a == 'promo' && strstr(ucwords($promo_name),'30% Off') ||
strstr(ucwords($promo_name),'Save 30%') && $b == 'yes')
{echo 'this is a 30% off promotion'; }
Im getting a little confused with what will take precedence etc. I need both $a == 'promo' and $b == 'yes' to be true at all times, with any 1 of the 2 strstr being true.
Any help much appreciated.
thanks
m,ike
The precedence of && is higher than ||. So you need to use some parentheses to make your statement work, as you expect:
elseif ($a == 'promo' && (strstr(ucwords($promo_name),'30% Off') || strstr(ucwords($promo_name),'Save 30%')) && $b == 'yes')
Try something like
if ((($a == "a") || ($b == "b")) && ($foo == "bar")) {
When I first studied boolean algebra in electronics, we were told that and was like a × and or like a +. This is true for operator precedence (a and b or c translates to a × b + c and hence (a × b) + c), and also helps for truth tables or complicated boolean expressions, expression development, etc.
a b a×b a+b
0 0 0 0
0 1 0 1
1 0 0 1
1 1 1 2=1
This is a good mnemonic, but don't ever say that to a mathematician ;-)
So, just to be clear, and has higher precedence than or so yo need parenthesis to do what you'd like : bool1 and (bool2 or bool3)
I am trying to do:
if(x != 1 || 2) echo 'okay';
With my code here:
if($_POST["timezone"] != ("Pacific/Midway" || "America/Adak" || "Etc/GMT+10" || "Pacific/Marquesas")) {
$timezone_error = 'Invalid timezone';
}
Whereas I put in information that did not equal, and $timezone_error was still not set, what is the proper OR operator that I should be using, or is this possible at all? I would rather not write $_POST['x'] != 1, $_POST['x'] != 2 all out separately as this is quite a long list.
what you want is something like this
$array = array("Pacific/Midway" , "America/Adak" , "Etc/GMT+10" , "Pacific/Marquesas");
if (!in_array($_POST["timezone"], $array){
$timezone_error = 'Invalid timezone';
}
Correct format would be:
if(x!= 1 || x!=2) echo 'okay';
I can't get this code to work
if ($title != 'Main' || $nSpace == 56 || $nSpace == 30 && $ifHome != 361)
So i settled for this code
if ($title != 'ArticleCategories' || $nSpace == 1)
if ($nSpace == 0 && $ifHome != 1)
So, i am now wondering how can i get those two lines into one line in the way so that it works? I know how to get multiple or || statements into one line but not the or || and and && statements together.
Use parens to group the logic together in a manner that makes sense for your program.
if ($title != 'Main' || $nSpace == 56 || ($nSpace == 30 && $ifHome != 361))