Here is my code
<?php
if( $_SERVER['REQUEST_URI']!="/index.php?task=join&" || $_SERVER['REQUEST_URI']!="/index.php?task=join&step=1"
|| $_SERVER['REQUEST_URI']!="/index.php?task=join&step=2" ) {
include ("inc/js/script.php");
}
?>
I need to say "if REQUEST_URI != /index.php?task=join& 'or' /index.php?task=join&step=1 'or' /index.php?task=join&step=2 >>> include inc/js/script.php
When i use && it work correctly but i think the correctly answer should be ||
What is the wrong please ?
It sounds to me like you want "AND" - or you could change the sense of it all into:
if (! (uri == first || uri == second || uri == third) )
If you think about it, the URI can't be both "/index.php?task=join&" and "/index.php?task=join&step=1", so it must be unequal to one of them - so using || in your current code will always return true.
|| means or, && means and. If or is what you're going for, use ||.
However, if you use ||, the condition will always evaluate to true, since $_SERVER['REQUEST_URI'] will always be either different from "/index.php?task=join&" or "/index.php?task=join&step=1", since it can't be both.
So I think you're actually looking for an and condition - &&.
Also, you should use strcmp for string comparison.
If I understood what you want :
I would suggest using $_GET and doing it like this :
<?php
if ($_SERVER["PHP_SELF"] == "/index.php" && $_GET['task'] == "join" && (isset($_GET['step'] && ($_GET['step'] == 1 || $_GET['step'] == 2)))
include_once("inc/js/script.php");
?>
The answer is && because you want it to be AND as you are comparing the same variable is not equal to different values.
You want the variable to be not this, not that, *AND* not the other.
If it uses OR (||), then it is allowed to be one of them, but as long as it is not all of them (which it obviously can't be).
Your English description of what you want to do is fine, but when you get to code, there's a translation error.
Here's the behavior you said you want:
if REQUEST_URI != /index.php?task=join& 'or'
/index.php?task=join&step=1 'or' /index.php?task=join&step=2 >>>
include inc/js/script.php
When you put it that way, it's clear that the "not" (the ! in !=) applies to all the URIs. So lets break out that NOT and use brackets to indicate that it applies to everything:
if not (REQUEST_URI = /index.php?task=join& 'or'
/index.php?task=join&step=1 'or' /index.php?task=join&step=2) >>>
include inc/js/script.php
Now to get us from English to near-code we just need to spell things out a bit more completely:
if ! (REQUEST_URI == /index.php?task=join& or
REQUEST_URI == /index.php?task=join&step=1 or
REQUEST_URI == /index.php?task=join&step=2)
include inc/js/script.php
This is essentially the solution Jon Skeet proposed.
As a further note, here's why your code works if you change the ||s to &&s. You've essentially rediscovered a well know rule of logic called De Morgan's law (referred to in Salman A's comment), which has two forms (where "<==>" means "if and only if"):
!(A || B) <==> !A && !B
!(A && B) <==> !A || !B
According to form 1 of De Morgan's law, the code above is therefore the same as
if (!REQUEST_URI == /index.php?task=join& and
!REQUEST_URI == /index.php?task=join&step=1 and
!REQUEST_URI == /index.php?task=join&step=2)
include inc/js/script.php
which is the same as
if (REQUEST_URI != /index.php?task=join& and
REQUEST_URI != /index.php?task=join&step=1 and
REQUEST_URI != /index.php?task=join&step=2)
include inc/js/script.php
Do you want the request uri to be:
a) Not equal to any of those things (&&)
or
b) Not equal to one or more (or all) of those things (||)
You want && I suspect.
Related
So I understand this - and comparing/checking values. However, I was messing about and noticed the outcome for all my tests were the same - some of which I was taught (a) didn't work or (b) was incorrect.
Note, I'm running PHP7. Okay, to my point. I was able to achieve the same outcome checking if a single value equals one of multiple options...
These work...why? Def not the way I learned.
if ($status == 'in-progress' || 'in-review')
// and even
if ($status == ('in-progress' || 'in-review')) // kind of similar to ASP.NET Razor
I normally would repeat the check, like so: if($stat == 'a' || $stat == 'b') or even in_array() which is essentially the same thing.
Is the first examples, correct? If not, why is it working? Or is this something frowned upon and not practiced - or maybe even something new?
First off to make it clear == has a higher precedence than ||. This means your two if statements look like this:
if (($status == 'in-progress') || 'in-review')
if ($status == ('in-progress' || 'in-review'))
Now for your first if statement regardless what value $status has and what the outcome of ($status == 'in-progress') is, since you have an OR in it and after it 'in-review' your if statement will always be true, since a non empty string is a truthy value.
For your second statement, this part ('in-progress' || 'in-review') comes literally down to TRUE || TRUE, which evaluates to TRUE. Now $status just needs to hold a truthy value and the if statement will be true.
No, that code will never work. || has a lower precedence than ==, so you're comparing $status against the first value, then boolean || "or" the other value
if (($status == 'foo') || ('bar'))
You have to compare the values individually:
if (($status == 'foo') || ($status == 'bar'))
And this gets tedious for many values. A quick hack is to use an array:
if (in_array($status, array('foo', 'bar', 'baz', 'qux', 'etc...')))
I am confuse with bellow code:
Fist code that is not working:
if ($_SESSION['userType'] != 'A' || $_SESSION['userType'] != 'S')
{
redirect('dashboard.php');
}
Second code that is working:
if (!($_SESSION['userType'] == 'A' || $_SESSION['userType'] == 'S'))
{
redirect('dashboard.php');
}
What is difference between both code?
I know you already have six answers to your question, but none of them uses plain English, so I'll make an attempt myself as well.
Let's look at this code step by step, splitting it up into smaller portions, and explaining each step exactly.
Code that isn't working
First you have this row:
if ($_SESSION['userType'] != 'A' || $_SESSION['userType'] != 'S')
Instead of looking at the full if clause already, let's divide it into two parts:
if ($_SESSION['userType'] != 'A')
if ($_SESSION['userType'] != 'S')
The first part will trigger any time that $_SESSION['userType'] is any value other than A.
The second part will trigger any time that $_SESSION['userType'] is any value other than S.
Now, you've joined them both together with an "or" operator, so that it's enough that one of them is true for the if clause to trigger. Let's see what happens when we try it out.
We set $_SESSION['userType'] to 'B' and go into the if clause. The first thing that happens is that PHP looks at the first part, if ($_SESSION['userType'] != 'A'), and finds that 'B' != 'A'. It doesn't need to go to the second part, because it already found that one of the parts of the if statement is true, and so it decides that the full if statement must also be true.
We set $_SESSION['userType'] to 'A' and go into the if clause. The first thing that happens is that PHP looks at the first part, if ($_SESSION['userType'] != 'A'), and finds that 'A' == 'A', so the first part is false. It then goes on to the second part, which is if ($_SESSION['userType'] != 'S'), and finds that 'A' != 'S'. Since this means that one of the parts of the if statement is true, it again decides that the full if statement must also be true.
Now notice what this means. Even if you send an 'A' to the if clause, it will still trigger because of the second part. And if you were to send an 'S', it will trigger because of the first part. So essentially, the full first if statement will trigger regardless of what $_SESSION['userType'] is set to. It's a tautology - it's always true.
Code that is working
This is your full if statement:
if (!($_SESSION['userType'] == 'A' || $_SESSION['userType'] == 'S'))
Let's ignore the ! for now, and divide it into the two parts of the or operator.
if ($_SESSION['userType'] == 'A')
if ($_SESSION['userType'] == 'S')
Notice that this is the logical opposite of the code you had that didn't work. The first row means "only accept an 'A'" and the second means "only accept an 'S'". So this code will trigger only if you give it either an 'A', or an 'S'.
Now, what happens if you put an ! in front of the whole thing, like you did?
The ! operator simply reverses whatever it is put in front of. So this changes the meaning from "either A or S" to "neither A nor S".
Summary
Your first example comes down to "any value whatsoever".
Your second example comes down to "any value, but not A, and also not S".
If you want to learn more of basic logic, I suggest looking at De Morgan's laws, as you were linked to in an above comment. This will give you an understanding of how and and or fits together.
Not...quite.
If I remember boolean logic correctly, the fault lies in order of operations.
if ($_SESSION['userType'] != 'A' || $_SESSION['userType'] != 'S') {
if userType equals A, this will not work...since the first operation is to check that it is not equal to A and ORs are left to right...so if the first is not true, the entire statement is false.
Your second approach translates to:
if (!($_SESSION['userType'] == 'A' || $_SESSION['userType'] == 'S'))
{
redirect('dashboard.php');
}
IF NOT userType equals A OR userType equals S which is why it works as you desire it to.
Try
if ($_SESSION['userType'] != 'A' && $_SESSION['userType'] != 'S')) {
which means IF userType is not A and userType is not S
I think that will give you what you are probably looking for. IE Only do what is in the loop if the userType is neither A, nor S.
if ($_SESSION['userType'] != 'A' || $_SESSION['userType'] != 'S') {
is more or less equivalent to
if (!($_SESSION['userType'] == 'A' && $_SESSION['userType'] == 'S')) {
first code that is not working
if ($_SESSION['userType'] != 'A' || $_SESSION['userType'] != 'S')
{
redirect('dashboard.php');
}
lets simplyfy it as under:
if (true || true) //the condition will be true or vice versa
{
redirect('dashboard.php');
}
Second code that is working:
if (!($_SESSION['userType'] == 'A' || $_SESSION['userType'] == 'S'))
{
redirect('dashboard.php');
}
and the simplified version:
if (!(true || true)) same as if (!(true)) //i.e. false or vice versa
{
redirect('dashboard.php');
}
so basically one is true and the other is false or vice versa so thats why they are acting diffrenetly.
I'm like to use this IF to redirect user based on permissions. But user is all time redirected to dashboard.
Actually i have set:
$perm_edit = '0';
$user_level = '1';
if ($perm_edit !== 1 || $user_level !== 1) {
header("Location: $url/dash.php?error=1"); exit;
}
|| operator require only one condition to go ahead.
What do I wrong?
The triple comparison operators are "strict", meaning they check type as well as value. You are comparing strings to numbers, which means they will always be false. Either turn them both into numbers, or just use double comparisons: $perm_edit != 1
It is because you are using the not identical to operator (!==). It does not do type juggling, which is what you need in this case.
In order to find out if two values, of different types, are equivalent, you must use the not equal to operator (!=):
if ($perm_edit != 1 || $user_level != 1) {
header("Location: $url/dash.php?error=1");
exit;
}
Another way to write that is:
if ( ! $perm_edit || ! $user_level) {
header("Location: $url/dash.php?error=1");
exit;
}
The reason that works is because PHP juggles the types. In other words, it turns 0 into false and 1 into true, and then the ! operator (also called the NOT operator) turns it into the opposite.
You should read up on comparison operators and operators in general.
I have an if statement that I want to control with having one field needing input and they have to pick one of the other 2 choices.
if(test1 && test || test3){
//Something here
}
Should I do it like this:
if(test1 && (test2 || test3)){
//do stuff
}
How would I go about doing this. I can't wrap my head around the logic...
if ($requiredField && ($optional1 || $optional2)) {
/* Do something */
}
For the /* Do something */ bit of code to be executed, the if statement has to evaluate to TRUE.
This means, that $requiredField must be TRUE, and so must be ($optional1 || $optional2).
For $requiredField to be TRUE, it just needs to be filled in - and for the second part: ($optional1 || $optional2) either optional1 or optional2 would do it.
Edit:
After rereading the question, it seems that I might have misunderstood you. If the user must enter one specific piece of information, and must choose only one (not both) out of two options - then the following should be used.
if ($requiredField && ($optional1 ^ $optional2)) {
/* Do something */
}
This means that $optional1 or $optional2 must be filled out - but not both of them.
From the sound of it, you want the latter:
if ($test1 && ($test2 || $test3)){
//do stuff
}
Think of it as two conditions needing to be met. This gives you those two conditions. The second condition just happens to be another condition. The first option you posted, however, is quite the opposite as it can allow execution if just $test3 is true
test1 && (test2 || test3) is very easy to understand from the first place - Choose test1 && (test2 || test3) means one the last two. Very clear.
test1 && test || test3 - doesn't seem to be correct:
test1 = false
test2 = false
test3 = true
false && false || true = true
doesn't actually fit your criteria.
... they have to pick one of the other 2 choices
I'm just throwing a guess out here. If you really want to ensure that one, but only one of the two other options are selected, then you need xor:
if ($required AND ($and_either XOR $or_other)) {
You can have 'nested' if statements withing a single if statement, with additional parenthesis.
if(test1 && (test2 || test3)){
//do stuff
}
Your logic is right but your sintax isnt, you should compare the values of the variables as show, or simply ignore them as saying you are trying to compare them as they are TRUE.
$test1=true;
$test2=true;
$test3=false;
if($test1==true && ($test2==true || $test3==true){ echo "YES";}
This will output YES.
I have a conditional statement which goes thusly:
if ($_POST['password'] == $_POST['repeat'] && $_SESSION['type'] == "admin")
But let's say I also want the conditional to evaluate true to users with type "superuser" (instead of "admin").
So I could, for example, write:
if ($_POST['password'] == $_POST['repeat'] && $_SESSION['type'] == "admin" || $_SESSION['type'] == "superuser")
But assuming PHP reads conditionals and equations from the left to the right, it's then possible for a "superuser" to have the conditional evaluate true even if "password" and "repeat" are not equal, since we're placing imaginary brackets around the two operands next to "&&", right?
I could add brackets to encapsulate the two operands for "||", but I recall faintly that I may have tried something in the past, and had it fail spectacularly.
Is there a better way to do this? Do brackets actually work (thus concluding that my memory is faulty? [memory leak? heh.])
Thanks!
Yes, parentheses will override the fact that && has a higher precedence than ||.
Haven't tested but try this:
if ($_POST['password'] == $_POST['repeat'] &&
($_SESSION['type'] == "admin" || $_SESSION['type'] == "superuser"))
Enclose the admin check in () and OR the 'type' check. Superuser should get checked first for optimal code.
($_SESSION['type'] == "superuser" || ($_POST['password'] == $_POST['repeat'] && $_SESSION['type'] == "admin") )
To get what you want you could:
if (($_POST['password'] == $_POST['repeat']) && ($_SESSION['type'] == "admin" || $_SESSION['type'] == "superuser"))
Which would evaluate to true when passwords match and if the user type is admin or super user.
Or, more verbosely:
$valid_password= $_POST['password'] == $_POST['repeat'];
$valid_user= $_SESSION['type'] == "admin" || $_SESSION['type'] == "superuser";
if ($valid_password && $valid_user)
// Do something