I want to make a function for a "secure" php page that will check the token(the one passed by post and the one from the session). But I don't want to write two if statements like this:
function CheckToken(){
if(isset($_POST['token']) && isset($_SESSION['token']))
if($_POST['token']==$_SESSION['token']) return true;
return false;
}
Can I do something like this(?):
function CheckToken(){
if(isset($_POST['token']) && isset($_SESSION['token']) && $_POST['token']==$_SESSION['token']) return true;
return false;
}
Here's all about the order in which those functions are executed (when using the and operator).So if you're using the AND operand then if the first conditions is false don't evaluate the second. I remember that vb.net had a solution to this problem(evaluating only the first function-if it is false don't evaluate the second one). So, is it safe to put everything on a single line(like I did in the second example)?
PHP does the same thing as the usual if statement evaluation in other major languages, that is, check from left to right.
So if you have
if (cond1 && cond2 && cond3)
Scenario 1:
If cond1 is true, it will then execute cond2, and then cond3.
Sample: https://3v4l.org/Ap9SQ
Scenario 2:
If let's say cond2 is false, then cond3 will be ignored.
Sample: https://3v4l.org/u9P4O
Same goes to OR
if (cond1 || cond2 || cond3)
If cond1 is true, cond2 and cond3 will be skipped.
Sample: https://3v4l.org/ZAZcD
So since your function is just returning true or false, you can even simplify it to something like this:
function CheckToken() {
return isset($_POST['token']) &&
isset($_SESSION['token']) &&
$_POST['token'] == $_SESSION['token'];
}
Split lines for readability. Also checkout isset manual as you can pass in multiple variables for empty checking.
Yes, there really is no difference to changing the order like that. It is perfectly safe, because all it's doing is changing the look of the script while the execution is the EXACT same.
It would be best to do the second option.
Related
I found an example php assignment statement online which maybe resembles a tertary conditional condensed statement, but not quite. Does anyone have insight as to how to read this assignment statement?
$access = $access || $note->uid == $user->uid && user_access('note resource view own notes');
My first guess was "assign to access whatever is in access, or if empty, whether uid values are equal and'd with the return of user_access." But I get the feeling that is not correct, as it seems illogical.
First have a look at the Operator Precedence
== comes before && comes before || comes before =
Thus your statement is more clear with adding the following parentheses:
$access = (
$access
||
(
($note->uid == $user->uid)
&&
user_access('note')
)
);
assign to access whatever is in access, or if empty,
Not quite: assign to $access the value true* when $access already evaluates to true (true, 1, "some string" etc), or
whether uid values are equal and'd with the return of user_access
Correct
And otherwise assign false. After this statement $access is always either true or false, even when $access === 'yes' before.
Note*: || and && are boolean operators, only capable of 'returning' true or false
I had this exact type of statement in a library way back, and it's basically an elaborate (or maybe just badly-styled?) null-check. Because PHP uses short circuit evaluation, the right-hand side of the or-expression will not evaluate if the left hand one was null.
In my php application i do the following check:
if(($images = $main->get_images($data['id'])) || ($videos = $main->get_videos($data['id']))){
(...)
if($videos){
(...)
}
if($images){
(...)
}
}
This operation sends back an error saying $videos is undefined. My guess is that if the first statement is true, the second wont be checked. Is there any neat way of preforming the second check, even is the first one is true, because in this case if images is true, videos will be evaluated as false
There isn't a way. You'll need to re-write it into something like this...
$images = $main->get_images($data['id']);
$videos = $main->get_videos($data['id']);
if($images || $videos){
(...)
if($videos){
(...)
}
if($images){
(...)
}
}
And just FYI... order of operations means you don't need to enclose the conditions in () brackets. Almost everything gets computed BEFORE the OR operator (including the && operator).
Good luck!
Joey
You can use empty() to see if a variable does not exist or is null e.g.
if(!empty($videos)) {
(...)
}
I have this if statement in my PHP:
if($_SESSION['usrName']!='test1'){
header('location:login.php');
}
But i want it to be something like this:
if($_SESSION['usrName']!='test1' or 'user'){
header('location:login.php');
}
But i cant figure out how to do it in PHP code. I have tried this:
if($_SESSION['usrName']!='test1','user'){
header('location:login.php');
}
And this:
if(($_SESSION['usrName']!='test1')||($_SESSION['usrName']!='user')){
header('location:login.php');
}
Can anybody help please?
You have to replace the || with &&. Because you only want to redirect when both conditions are true.
if(($_SESSION['usrName']!='test1') && ($_SESSION['usrName']!='user')){
header('location:login.php');
}
if (!in_array($_SESSION['usrName'], array('test1', 'user')) {
header('location:login.php');
}
This checks if variable $_SESSION['usrName'] is not in list of strings to simplify additional allowed user.
As others have said, you need to be careful with your boolean logic - (NOT X) || (NOT Y) is equivalent to NOT (X AND Y), whereas what you want is NOT (X OR Y) which is equivalent to (NOT X) AND (NOT Y).
For this particular situation, there are also a couple of other options, although none as neat as the invalid syntaxes you tried.
First, there is in_array(), which is easy to read, but not very efficient if you use it a lot with long lists (for a simple case like this, it's not worth worrying about performance, though):
$allowed_users = array('test1', 'user');
if ( ! in_array($_SESSION['usrName'], $allowed_users ) { ... }
Or, you can build a hash with the usernames as keys; this is more efficient as the list grows, because PHP can check for a key without looping through the whole list:
$allowed_users = array('test1' => true, 'user' => true);
if ( ! array_key_exists($_SESSION['usrName'], $allowed_users) ) { ... }
// Or, if you don't mind PHP raising a few notices about accessing undefined keys
if ( ! $allowed_user[ $_SESSION['usrName'] ] ) { ... }
Finally, you can use a switch statement, with the labels falling through, and a default case acting as the "else":
switch ( $_SESSION['usrName'] )
{
case 'test1':
case 'user':
// These users are allowed :)
break;
default:
header('location:login.php');
}
Which, if any, of these you choose to use will depend on how you expect the code to grow in future, but they're useful tricks to know.
Your last attempt is almost correct.
However...
if (var != something || var != something-else)
...will always be true, because one of those conditions will always match. Even if it's equal to one side, it won't be equal to the other.
When you're testing two negatives like that, you need to use AND (&&) instead of OR (||).
if (($_SESSION['usrName']!='test1') && ($_SESSION['usrName']!='user'))
This will match if it's not equal to one, and also not equal to the other.
Currently, you're checking if either one of conditions are true. The last condition will evaluate to true if either one of the conditions are correct. I assume you're trying to check if both the the conditions are true. In that case, you'll need && instead of ||.
Try:
if( ($_SESSION['usrName'] != 'test1') && ($_SESSION['usrName'] != 'user') ) {
header('location:login.php');
}
You need to do something like:
if($_SESSION['usrName'] != 'test1' and $_SESSION['usrName'] != 'user'){
header('location:login.php');
}
The first attempt of yours is equivalent to:
if(($_SESSION['usrName']!='test1') or 'user'){
header('location:login.php');
}
Second seems like invalid syntax
Third is almost right, you just need to replace || with and or &&, as anything will be unequal to either 'user' or 'test1'
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 the following if statement
if (isset($part->disposition) and ($part->disposition=='attachment'))
Problem is the second part of that statement, i also need to include this;
($part->disposition=='inline')
The statement needs to work if the disposition is attachment or if its inline.
This must help:
if (isset($part->disposition) && ($part->disposition=='attachment' || $part->disposition=='inline'))
doesn't that work:
if (isset($part->disposition) and (($part->disposition=='attachment') or ($part->disposition=='inline')))
In case you may be going to have more than two options in the future you might also be interested in in_array(needle, haystack)
if (
isset($part->disposition)
&& in_array($part->disposition, array('attachment', 'inline', 'option3', 'option4'))
)
If you want the equivalent of === (strict comparison, instead of == like in your example) set the third parameter of in_array() to true.
This try (for efficiency):
if (isset($part->disposition))
{
if($part->disposition=='attachment' || $part->disposition=='inline')
{
// perform task
}
}