PHP Conditional logic, specific order? - php

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

Related

PHP - if single value equals multiple options

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...')))

Display HTML if two conditions are true or another two are true or third part of conditions are true

I have php if statement that should display certain HTML code if two conditions are true or another two are true or third part of conditions are true.
I have several arrays - $Options_arr, $MoreOptions_arr, $Special_arr .
To explain in the easiest possible way I want to do this:
if(!empty($Options_arr[0]) && $Options_arr[0]!="") or
(!empty($MoreOptions_arr[0]) && $MoreOptions_arr[0]!="") or
(!empty($Special_arr[0]) && $Special_arr[0]!="")
{?> some HTML here
All help will be appreciated thank you.
empty() already checks for empty string "" so it's shorter:
if(!empty($Options_arr[0]) || !empty($MoreOptions_arr[0]) || !empty($Special_arr[0])) {
//some HTML here
}
BragG, you can use elseif
Like:
if((!empty($Options_arr[0]) && $Options_arr[0]!="") ||
(!empty($MoreOptions_arr[0]) && $MoreOptions_arr[0]!="") ||
(!empty($Special_arr[0]) && $Special_arr[0]!=""))
{
// some html or any code
}
I hope that is what you were looking for..
Feel free to ask any question.
You are just missing some brackets. Also || is more frequently used than OR
if((!empty($Options_arr[0]) && $Options_arr[0]!="") || (!empty($MoreOptions_arr[0]) && $MoreOptions_arr[0]!="") || (!empty($Special_arr[0]) && $Special_arr[0]!="")){
echo '<p>hello</p>';
}
You're basically already there...
if (
(!empty($Options_arr[0]) && $Options_arr[0]!="")
|| (!empty($MoreOptions_arr[0]) && $MoreOptions_arr[0]!="")
|| (!empty($Special_arr[0]) && $Special_arr[0]!="")
){
...do something
Basically you write an if statement that resolves if any of the sub-statements are true by joining the sub-statements together with ORs

what i should use && or ||

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.

Using OR in a IF

Any ideas why this isn't working?
if($page->Slug != 'water-filters' || $page->Slug != 'pet-care' || $page->Slug != 'books') {
//do something
}
I think you mean AND instead of OR because you're using not equals.
By using not equals in the way you are the statement will always be true, if $page->Slug equals 'water-filters' it doesn't equal 'pet-care' and hence the if statement as a whole returns true.
if($page->Slug != 'water-filters' && $page->Slug != 'pet-care' && $page->Slug != 'books')
{
//do something
}
I'm guessing that "do something" is always getting executed?
if($page->Slug != 'water-filters' || $page->Slug != 'pet-care' || $page->Slug != 'books')
{
//do something
}
For any value of $page->Slug, it will always be not equal to ONE of those three conditions, therefore at least one (technically, at least two) of the statements will always be true. Since you're using an 'OR' as long as one of the three statements is true, the whole thing will be true.
Therefore, this is essentially saying
if (true) {
//do something
}
$page->Slug is either 'water-filters' or 'pet-care' or 'books'
Try
== or == or ==
or
!= and != and !=
:-D
If the Slug is not "water-filters" or is not "pet-care" or is not "books"...
Well, if it's one of those, or any other value, it's by definition not the other two (or not all three). So this condition is always true.
Aside from what the others have said above, which are correct also, try this syntax for readability.
if(!in_array($page->Slug, array('water-filters', 'pet-care', 'books')) {
// Do something
}

Why doesn't this if test work?

My site requires a login that establishes permissions based on the user. In the photo listing of the site, I must determine if a particular photo will be displayed if the user has guest access only. So I thought that this if else statement would work:
if (!($mysql_row['guest_access'] == 'NO') AND ($_SESSION['user_level'] == 'GUEST')) {
// show the photo if it isn't private and the user isn't a guest
But it doesn't.
However, if I separate this test into three lines then it works just fine.
$is_private_photo = $mysql_row['guest_access'] == 'NO';
$is_guest = $_SESSION['user_level'] == 'GUEST';
$both_private_and_guest = ($is_private_photo AND $is_guest);
if (!$both_private_and_guest) {
// show the photo if it isn't private and the user isn't a guest
What is wrong with the first version?
Your first if is
if (!($mysql_row['guest_access'] == 'NO') AND ($_SESSION['user_level'] == 'GUEST'))
Which is actually interpreted like this :
if (
(!($mysql_row['guest_access'] == 'NO'))
AND ($_SESSION['user_level'] == 'GUEST')
)
The ! is only applied to the first condition, not both, because it has a higher level of priority than AND (see Operator Precedence)
Your condition should probably be re-written with some additional parentheses :
if (!(($mysql_row['guest_access'] == 'NO') AND ($_SESSION['user_level'] == 'GUEST')))
So the ! is applied to the whole condition.
The logical not operation needs to be applied to the AND results, but in your code sample it only applied to the first clause (NOT has higher precedence than AND). You can solve it by grouping both conditions:
if (!(($mysql_row['guest_access'] == 'NO' AND ($_SESSION['user_level'] == 'GUEST'))) {
The not operator (!) only covers the first condition so either add another bracket, or do this
if ( $mysql_row['guest_access'] != 'NO' AND...
It's because you put the parentheses in the wrong place in your first version. The equivalent form of the second version is
if (!$is_private_photo AND $is_guest)
which is clearly not what you intended.
Make it like this:
if (($mysql_row['guest_access'] != 'NO') AND ($_SESSION['user_level'] != 'GUEST')) {
Your '!' is not being applied to the 'AND' statement...it is only being applied to the ($mysql_row['guest_access'] == 'NO') statement.
You are only negating the first condition. Try this:
if (!($mysql_row['guest_access'] == 'NO' AND $_SESSION['user_level'] == 'GUEST')) {
Your negation operator does not apply as expected. You should use something like:
if ( ! (($mysql_row['guest_access'] == 'NO') AND ($_SESSION['user_level'] == 'GUEST')) )
if ( ! ($mysql_row['guest_access'] == 'NO') OR ! ($_SESSION['user_level'] == 'GUEST') )

Categories