I have been making stuff in PHP for a while, everything is always fine. But today I don't get this statement. Why is it always true?
if ($action != 1 || $action != 2) echo true; // TRUE for 0, 1, 2, 3
But the reverse logic
if ($action == 1 || $action == 2) echo true; // FALSE for 0, 3 TRUE for 1, 2
The first expression blows my mind. I guess I don't understand something very very basic, not in PHP but in the Universe, so I don't get it here. I thought that if (FALSE || TRUE) == FALSE, but it isn't a case for second example. It works as expected.
So, where is the answer how to say that: "If the variable is not 1 OR 2 - echo true". I don't understand why my if ($var != 1 OR $var != 2) echo true; doesn't work as I expect.
Negation of ($action != 1 || $action != 2) is ($action == 1 && $action == 2). You can see for yourself that the latter is always false because variable can not be both 1 and 2 at the same time. Therefore the original condition is bound to be always true.
It is working as it has to work. See the doc http://php.net/manual/en/language.operators.logical.php
$a || $b returns TRUE if either $a or $b is TRUE.
If you try like this, hope it will make sense, see the comment on every line
$action = 0;
var_dump($action != 1 || $action != 2); //here (true || true)
$action = 1;
var_dump($action != 1 || $action != 2); //here (false || true)
$action = 2;
var_dump($action != 1 || $action != 2); //here (true || false)
$action = 3;
var_dump($action != 1 || $action != 2); //here (true || true)
Condition OR will search for first TRUE result, your code will give TRUE all the time as any value will be even not 1 or 2.
From you example if $action = 1 then the condition $action != 2 will give true, also if $action = 2 then $action != 1 will give TRUE.
For (If the variable is not 1 OR 2 - echo true) use this:
if(!in_array($action, array(1,2)) echo "true";
EDIT:
You can also check it like this:
if(!($action == 1 || $action == 2)) echo "true";
if ($action == 2 || $action == 1) echo true; // FALSE for 0, 3 TRUE for 1, 2
Works as intended. Its basically "echo true if $action is either 1 or 2".
Related
This question already has answers here:
Why does non-equality check of one variable against many values always return true?
(3 answers)
Closed 6 years ago.
The first one with equals will work and I would expect that. But the second is not working as expected.
$nicktest = "new";
if ($nicktest == "new" || $nicktest == "fun" || $nicktest == "norm" || $nicktest == "pvp")
{
$odpoved = "Ok it works.";
echo $odpoved;
return;
}
$nicktest = "new";
if ($nicktest != "new" || $nicktest != "fun" || $nicktest != "norm" || $nicktest != "pvp")
{
$odpoved = "Ok it works too why?";
echo $odpoved;
return;
}
Your 4 conditions get the following evaluation:
false, true, true, true
Now,
if (false || true || true || true) {
// Code block is actually evaluated
}
If you would happen to have:
if (false || false || false || false) {
// Code block wouldn't be evaluated
}
Under this scheme, at least one true condition would get the code to be evaluated
<?php
include_once("php_includes/check_login_status.php");
if($user_ok != true){
header("location: login.php");
exit();
}
?>
<?php
$result = mysqli_query($db_conx, "SELECT active FROM profilepage WHERE username='$u'") or die(mysqli_error($db_conx));
$row = mysqli_fetch_assoc($result) or die ("$u not found");
$a_check = $row['active'];
if ($u == $log_username && $user_ok == true && $a_check = 1){
echo include_once("videofeedform.php"); }
else ($user_ok != true && $a_check = 1 or $user_ok = true && $a_check = 1);
{ echo "viewers should only see this"; }
exit();
if($u == $log_username && $user_ok == true && $a_check = 0 or $u != $log_username && $user_ok == true && $a_check = 0 or $u != $log_username && $user_ok != true && $a_check = 0)
($a_check = 0); {
echo ' Video is going to be added here'; }
exit();
?>
ok so basically I am trying to make a module work only if it has been activated to work by the user. Only the owner of the pages sees what they is mean to and the viewer only sees what they are meant to so that part works perfect however i need to tell the script to do these IF's only if the data inside the row match 1 and if they do not match 1 (e.g 0) then they do something else. I believe the current search is only looking for a number of rows called active what is owned by the user and if it is then do...... I was wondering how I would make the query look inside the row to find the data it needs to execute as it just seems like it is just executing when it finds 1 row that matches
okay there is a decent amount wrong with this script.
you never show us what $log_username or $user_ok so I cannot help to evaluate whether those contain the correct values in your script. We'll just assume they do.
You must brush up on your usage of Comparison Operators in php.:
http://www.php.net/manual/en/language.operators.comparison.php
throughout the conditionals(if, elseif, etc..) in your script you have things like:
if ( $a_check = 1 )
but with a single '=' you are assigning the integer value 1 to the variable $a_check, this is basically the same thing as saying:
if (1)`
which evaluates to true in your if statement (any integer value other than 0 will always evaluate to true).
similarly the line
if ( $a_check = 2 )
is the same as
if (2)
and would also evaluate to true
as aldanux mentioned in his comment above, if you would like to compare if 2 variables are equal you should use ==.
if ( $var1 == $var2 )
if they are equal this will evaluate to true.
More issues with conditionals:
http://www.php.net/manual/en/control-structures.elseif.php
this block:
if ($u == $log_username && $user_ok == true && $a_check = 1){
echo include_once("videofeedform.php"); }
else ($user_ok != true && $a_check = 1 or $user_ok = true && $a_check = 1);
{ echo "viewers should only see this"; }
exit();
should be more like:
if ($u == $log_username && $user_ok == true && $a_check == 1){
echo include_once("videofeedform.php");
}
else if ($user_ok != true && $a_check == 1 or $user_ok == true && $a_check == 1)
{
echo "viewers should only see this";
exit(); //move exit inside the elseif block
}
fixed conditionals
use elseif since you want to evaluate another expression (e.g. $user_ok != true && $a_check == 1 or $user_ok == true && $a_check == 1),
remove semicolon from the end of your else statements
move exit() inside the elseif block (as you currently have the script would always exit on that line).
also an additional comment. the expression:
else if ($user_ok != true && $a_check == 1 or $user_ok == true && $a_check == 1)
is saying i don't care is $user_ok is true or false as long as $a_check equals one. This is the same thing as doing:
else if ($a_check == 1)
though... now im thinking you just want to exit if your previous if statment false:
if ($u == $log_username && $user_ok == true && $a_check == 1) //if this fails, exit
so your code there would actually look something more like:
if ($u == $log_username && $user_ok == true && $a_check == 1){
echo include_once("videofeedform.php");
}
else{ //just remove the expression from here
echo "viewers should only see this";
exit(); //move exit inside the elseif block
}
these same issues discussed above exist with your last if statement.
I'm sorry for the vaguely described title. This is what I want:
if($a[$f] === false || $a[$g] === false || $a[$h] === false || $a[$i] === false || $a[$j] === false)
{
// do something
}
I want to do something with the condition that actually triggered the statement (if a[$f] = true and a[$g] = false, I want to do something with $g).
I know that in this case, the first statement that went true (i.e. $a[$g] == false) triggers. But is there any way to do something with $g? I've never seen this in my programming life before and can't seem to find anything about it.
Thanks in advance.
--- Edit ---
I forgot to mention: I'm using a function on all the array data. So, shortened, I get this:
if(valid($a[$f]) === false || valid($a[$g]) === false)
{
// do something
}
--- Edit 2 ---
This piece of OOP-based PHP, where I'm in a class, is my code.
if($this->validatedText($product[$iName]) == false ||
$this->validatedUrl($product[$iUrl]) == false ||
$this->validatedNumber($product[$iTax]) == false ||
$this->validatedValuta($product[$iPrice]) == false ||
$this->validatedText($product[$iArticleNumber]) == false ||
$this->validatedText($product[$iDescription]) == false ||
$this->validatedText($product[$iMetaDescription]) == false ||
$this->validatedText($product[$iTitle]) == false)
{
// do something with the first iVariable
}
Simplest solution will be
if(false!==($sIndex = array_search(false, $a, 1)))
{
//your $sIndex is first index with false value
}
if you want all keys, you may use array_filter(), like this:
$rgFalse = array_keys(array_filter($a, function($x)
{
//here valid is your function
return false===valid($x);
}));
What I'm trying to achieve is a nested condition like if ((a = true && b = true) or (c = true && d = true)) {...}. This doesn't seem to be working for me.
To further explain: I have two variables in what we could call a 'top', and two variables in what we could call a 'bottom'. What I need to do is execute code if variables are true in both 'top' and 'bottom'.
To more succinctly illustrate:
if ((t1 = true && b1 = true) or
(t1 = true && b2 = true) or
(t2 = true && b1 = true) or
(t2 = true && b2 = true)
) {
...do some stuff...
}
I'm tempted to call it 'conditional statement for lattice problem'... except it isn't really a lattice problem... but it does sort of look like a lattice if you drew it |X| ... s'yeah, you're amazing if you can tell me a good way to do this, and you're super amazing if you can tell me what I ought to call it.
= is used for assignment, == is used to test for equality, === is used to test for equality and equal types. You need to use either == or ===, depending on whether t1, t2, b1, b2 are already boolean or something else. Also the stuff that Adam said, except that or is perfectly valid.
You need to use two equal signs == instead of =. Also, your variables need to have $ in front of them. And your "or" should be ||.
The logic is ok.
It should look like this:
if (($t1 == true && $b1 == true) ||
($t1 == true && $b2 == true) ||
($t2 == true && $b1 == true) ||
($t2 == true && $b2 == true)
) {
...do some stuff...
}
change condition
if (($t1 == true && $b1 == true) or
($t1 == true && $b2 == true) or
($t2 == true && $b1 == true) or
($t2 == true && $b2 == true)
)
= is assignment operator == is comparison operator.
This may be the way my server is set up, but I'm banging my head against the wall. I'm trying to say that if $action has no value or has a value that is not "add" or "delete" then have an error, else keep running the script. However, I get an error no matter what $action is.
$action = $_GET['a'];
if((!isset($action)) || ($action != "add" || $action != "delete")){
//header("location:index.php");
echo "error <br>";
}
$action is being set properly and if run something like if($action =="add") it works. This is on my local host, so it could be a settings issue.
Your logic is slightly off. The second || should be &&:
if ((!isset($action)) || ($action != "add" && $action != "delete"))
You can see why your original line fails by trying out a sample value. Let's say $action is "delete". Here's how the condition reduces down step by step:
// $action == "delete"
if ((!isset($action)) || ($action != "add" || $action != "delete"))
if ((!true) || ($action != "add" || $action != "delete"))
if (false || ($action != "add" || $action != "delete"))
if ($action != "add" || $action != "delete")
if (true || $action != "delete")
if (true || false)
if (true)
Oops! The condition just succeeded and printed "error", but it was supposed to fail. In fact, if you think about it, no matter what the value of $action is, one of the two != tests will return true. Switch the || to && and then the second to last line becomes if (true && false), which properly reduces to if (false).
There is a way to use || and have the test work, by the way. You have to negate everything else using De Morgan's law, i.e.:
if ((!isset($action)) || !($action == "add" || $action == "delete"))
You can read that in English as "if action is not (either add or remove), then".
No matter what $action is, it will always either not be "add" OR not be "delete", which is why the if condition always passes. What you want is to use && instead of ||:
(!isset($action)) || ($action !="add" && $action !="delete"))
You're saying "if it's not set or it's different from add or it's different from delete". You realize that a != x && a != y, with x != y is necessarily false since a cannot be simultaneously two different values.
You could also try:
if ((!isset($action)) || !($action == "add" || $action == "delete")) {
// Do your stuff
}
For future reference, you can quickly create a truth table to check if it evaluates the way you want... it's kind of like Sudoku.
(!isset($action)) && ($action != "add" && $action != "delete"))
Example:
column 1 is issetaction, column 2 and 3 evaluates !="add","delete" respectively
if($a=add) T && (F && T) => T && F => FALSE
if($a=delete) T && (T && F) => T && F => FALSE
if($a=nothing) T && (T && T) => T && T => TRUE
I think this is the best and easiest way to do it:
if (!(isset($action) && ($action == "add" || $action == "delete")))
Not an answer, but just for the sake of code formatting
if((isset($_GET['a'])) $action=$_GET['a']; else $action ="";
if(!($action === "add" OR $action === "delete")){
header("location: /index.php");
exit;
}
Note the exit; statement after header(). That's the important thing. header() does not terminate script execution.