22

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.

8
  • 1
    there is no sense in checking if $action is set, if you set it on the previous line Commented Jul 31, 2010 at 5:33
  • Shrapnel, if nothing is in the "?a=xxx" part of the url $action should be null. I think if I was setting $action to a static variable you would be right. Yet, because the user enters data there is a chance for problems. Correct me if I'm wrong. Commented Jul 31, 2010 at 5:39
  • 1
    oops, my bad. isset() return false on null variables. Anyway you should check if $_GET['a'] set, not $action. Or you will get "Undefined index" error. Commented Jul 31, 2010 at 5:46
  • Can you explain the "index not set" error? I've never heard of that. Commented Jul 31, 2010 at 5:48
  • error_reporting(E_ALL); <- just add this line to your config file/top of script and see what really happens in your code :) Commented Jul 31, 2010 at 5:53

7 Answers 7

32

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".

Sign up to request clarification or add additional context in comments.

Comments

12

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"))

1 Comment

@dumbledor I think this was the easiest way to modify my original code and explain what I did wrong.
3

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.

Comments

3

You could also try:

if ((!isset($action)) || !($action == "add" || $action == "delete")) {
  // Do your stuff
}

Comments

1

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.

Comments

0

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

Comments

0

I think this is the best and easiest way to do it:

if (!(isset($action) && ($action == "add" || $action == "delete")))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.