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.
Related
if(!isset($_GET['new_quiz']) || !isset($_GET['view_quiz']) || !isset($_GET['alter_quiz'])){
echo "No";
}
else{ echo "Yes"; }
When I go to index.php?view_quiz, it should give result as Yes, but it results as No. Why?
My Other Tries:
(!isset($_GET['new_quiz'] || $_GET['view_quiz'] || $_GET['alter_quiz']))
( ! ) Fatal error: Cannot use isset() on the result of an expression
(you can use "null !== expression" instead) in
C:\wamp\www\jainvidhya\subdomains\teacher\quiz.php on line 94
(!isset($_GET['new_quiz'],$_GET['view_quiz'],$_GET['alter_quiz']))
NO
You may find than inverting the logic makes the code easier to read, I also like to have a more positive idea of conditions as it can read easier (rather than several nots means no).
So this says if anyone of the items isset() then the answer is Yes...
if(isset($_GET['new_quiz']) || isset($_GET['view_quiz']) || isset($_GET['alter_quiz'])){
echo "Yes";
}
else{ echo "No"; }
Note that I've changed the Yes and No branches of the if around.
You are probably looking for
if(!isset($_GET['new_quiz']) && !isset($_GET['view_quiz']) && !isset($_GET['alter_quiz'])){
echo "No";
}
else {
echo "Yes";
}
which will print Yes if none of new_quiz, view_quiz and alter_quiz are present in the URL. If this is not your desired outcome, please elaborate on your problem.
#paran you need to set a value for view_quiz=yes for example
if(!isset($_GET['new_quiz']) || !isset($_GET['view_quiz']) || !isset($_GET['alter_quiz'])){
echo "No";
}
else{ echo "Yes"; }
and the url
index.php?new_quiz=yes
index.php?view_quiz=yes
index.php?alter_quiz=yes
All Will return true
isset()allows multiple params. If at least 1 param does not exist (or is NULL), isset() returns false. If all params exist, isset() return true.
So try this:
if( !isset( $_GET['new_quiz'], $_GET['view_quiz'], $_GET['alter_quiz']) ) {
First, to answer your question:
When I go to index.php?view_quiz, it should give result as Yes, but it results as No. Why?
This is becaue this
if(!isset($_GET['new_quiz']) || !isset($_GET['view_quiz']) || !isset($_GET['alter_quiz'])){
checks if either one of your parameter is not set, which will always be the case as long as you are not setting all three parameter simultaneously like this:
index.php?alter_quiz&view_quiz&new_quiz
As #nigel-ren stated, you may wan't to change that logic to
if(isset($_GET['new_quiz']) || isset($_GET['view_quiz']) || isset($_GET['alter_quiz'])){
echo 'Yes';
which checks if at least one parameter is set.
If you wan't to check if there is only one of the three parameters set, you would have to work with XOR (which is slightly more complicated)
$a = isset($_GET['new_quiz']);
$b = isset($_GET['view_quiz']);
$c = isset($_GET['alter_quiz']);
if( ($a xor $b xor $c) && !($a && $b && $c) ){
echo 'Yes';
(based on this answer: XOR of three values)
which would return true if one and only one of the three parameters is set.
But - and this is just an assumption, please correct me if I'm wrong - I think what you are trying to achieve are three different pages (one for creating a quiz, one for viewing it and one for editing it). Therefore, you will likely run into a problem with your current setup. For example: What would happen if a user calls the page with multiple parameters, like
index.php?alter_quiz&view_quiz
Would you show both pages? Would you ignore one parameter? I would recommend to work with a single parameter to avoid this problem in the first place. For example site which can take the values alter_quiz, view_quiz or new_quiz. E.g.:
index.php?site=alter_quiz
Then you can work like this:
// check if site is set before getting its value
$site = array_key_exists( 'site', $_GET ) ? $_GET['site'] : NULL;
// if it's not set e.g. index.php without parameters is called
if( is_null($site) ){
// show the start page or something
}else{
$allowed_sites = ['new_quiz', 'view_quiz', 'alter_quiz'];
// never trust user input, check if
// site is an allowed value
if( !in_array($site, $allowed_sites, true) ){
die('404 - This site is no available');
}
// here you can do whatever your site should do
// e.g. include another php script which contains
// your site
include('path/to/your/site-' . $site . '.php');
// or echo yes
echo 'Yes';
}
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.
I have a line of code that scans a dataset:
dataset:
+117251093918
+1174418217128
0112347063455555
php line of code:
if (substr($row['someData'],0,3) == "011")
{
//do stuff
}
+117251093918
+1174418217128
0112347063455555
I would expect to find 1 result in this dataset, however all 3 results are found according to php. any thoughts as to why?
If you want to make sure you compare strings on both sides, use a triple =:
if (substr($row['someData'],0,3) === "011")
That way php will not convert any variable types to make the comparison work; both content and variable type now have to be equal.
In your case both sides are converted to integers, see the following example:
var_dump("+11" == "011");
returns true
and this example:
var_dump("+11" === "011");
returns false.
Check the manual for more details.
You should use ===. The operator == casts between two different types if they are different, while the === operator performs a 'typesafe comparison'. That means that it will only return true if both operands have the same type and the same value.
In the example below, the first for loop shows why it returns good. The === exhibits typesafe comparison, it means unless the two values are of the same type and equal, it will return false. Whereas, == returns true regardless of the types, it just has to be equal.
<?php
// assume your row['somedata'] is this
$r = +11;
//returns good
if ((substr($r,0,3)) == "+11")
{
echo "Good";
}
//doesn't return any
if ((substr($r,0,3)) === "+11")
{
echo "Good One";
}
?>
A few days ago I started implementing simple security function to my project to prevent users from viewing customers added to database by other users. When I was doing this, I got confused because I realized that standard logical operators works in weird way.
This is the code I initially wrote:
if($current_user_id != $session_user_id || access_level($session_user_id) != 3) {
header('Location: logout.php');
exit();
}
It means that if stored customer that you are trying to view doesn't belong to You or Your access level isn't 3 (administrator) you will be logged out. It should work according this:
http://www.w3schools.com/php/php_operators.asp
They say that || means "True if either condition 1 or condidtion 2 is true", so if any of conditions doesn't fail it should allow access. Of course it isn't, script behave as only first condition is written, meaning if you are admin so your access level is 3 and you are viewing not your customer - you still will be logged out.
This is minor modification that started to work:
if($current_user_id != $session_user_id && access_level($session_user_id) != 3) {
header('Location: logout.php');
exit();
}
After switching to && which means "True if both condition 1 and condition 2 are true"
it started to work correctly, meaning you might not be owner of customer but if you are admin you will be allowed to access and not logged out.
At this point I'm afraid I understand it backwards, could someone explain why it doesn't seem logical? And how exactly it works? Thank you in advance.
Your logic is that the user should be allowed access if:
They are the owner, OR
The are an administrator
By this logic, you might construct this statement:
if( $user == $owner || access_level($user) == 3) {
// allow access
}
But you're using the negative position, ie. disallowing access if they are NEITHER the owner NOR an administrator. This means you have to negate the entire if statement.
Looking at the truth tables for || and &&:
A B A||B A&&B
0 0 0 0
0 1 1 0
1 0 1 0
1 1 1 1
You can see from this that in order to get the opposite of A||B, we need !A && !B:
A B !A !B A||B !A&&!B
0 0 1 1 0 1
0 1 1 0 1 0
1 0 0 1 1 0
1 1 0 0 1 0
So to write this, you do the following:
if( !($user == $owner) && !(access_level($user) == 3) ) { /* deny access */ }
Which can of course be written as:
if( $user != $owner && access_level($user) != 3) { /* deny access */ }
This:
it means that if stored customer that you are trying to view doesnt belong to You or Your access level isnt 3 (administrator) you will be logged out.
Does not entail this:
if any of conditions doesnt fail it should allow access
See De Morgan's law.
The first statement is essentially (!a || !b). Negating that (i.e., !(!a || !b)) actually switches to operator to become: (a && b).
Therefore, your second statement should read:
if both of the conditions don't fail, the user should be allowed to access [whatever]
Well, here you are:
$a && $b means that the condition is true if $a and $b are set to true.
$a || $b means that $a or $b (or both) must be set to true.
!$a && $b means that $a must be false and $b must be true
!$a || $b means that $a must be false or $b must be true
$a != $b means that $a must be not equal to $b
$a == $b means that $a must be equal to $b
$a > $b means that $a must be greater than $b
$a < $b means that $a must be less than $b
and so on...
They are Comparison Operators, check it out!
In your first example your using the OR operator but expecting to match 2 conditions for the following code, but one or the other could be matched.
E.G so if the user is not user level 3 it will logout regardless if
$current_user_id != $session_user_id or visa versa.
Using the AND operator means both conditions must be matched before logging out.
Suppose $current_user_id = 3, $session_user_id = 5, and access_level($session_user_id) level = 3. That means $current_user_id != $session_user_id is true, and access_level($session_user_id) != 3 is false. || is true if either of the conditions is true, so the if succeeds and the user is logged out.
Or suppose $current_user_id = 3, $session_user_id = 3, and access_level($session_user_id) level = 2. That means $current_user_id != $session_user_id is false, and access_level($session_user_id) != 3 is true. Again, this means the || is true, so the if succeeds and the user is logged out.
I was trying out a PHP "if" statement in which I want two things to be true: that $myvar is equal to 1 and that $myvar2 is equal to 2. However when I tried this:
if($myvar=='1', $myvar2=='2') {
header("location:index.php");
}
It failed to work. Is there a way to set up one if statement to contain these two variables like I have presented?
Thank you
You can use the boolean AND operator (&&)
if($myvar=='1' && $myvar2=='2') {
header("location:index.php");
}
Here's a full list of operators: http://php.net/manual/en/language.operators.logical.php
This will do. It is essential that you learn more about operators and flow control.
if($myvar=='1' && $myvar2=='2') {
header("location:index.php");
}
You need to use "and" operator &&
The && operator is the same as writing x='1' AND y='2',
So in ur case
if($myvar=='1' && $myvar2=='2') {
You can read more about PHP's operators at http://php.net/manual/en/language.operators.logical.php