1

I'm having trouble with sanitizing user input, where I don't know, if POST-Data has been sent or not. When I just do this to check:

if ($_POST["somedata"] == 2)
  DoSomething();

I will get an error notice with error_reporint = E_ALL, that $_POST["somedata"] may not be defined (e.g. when the page is loaded without the form).

So I do this check now:

if (isset($_POST["somedata"]) && $_POST["somedata"] == 2)
  DoSomething();

This doesn't output an error but it looks very unstable to me. I'm not sure if I just have luck with my PHP-Version or the simplicity of the statement. Is it also safe to use, when the if-statement is more complex, as long as the order of these two items are the same? Is it safe to use with all PHP-Versions?

Brainiac
  • 191
  • 1
  • 12
  • It is not unstable and will be safe, as long as the order stays the same. Since you use `a && b`, b will not be evaluated if a is not true (and hence you do not get the undefined index error anymore) – kero Apr 10 '15 at 13:17
  • This works because of short circuiting which PHP does! – Rizier123 Apr 10 '15 at 13:18

4 Answers4

2

Using isset in combination with a lazy-and (&&) is relatively correct (it prevents strictness warnings). A more advanced way would be to have automatic input checking against a schema or model.

You could have:

$schema = array(
    "somedata" => "number"
);

Using the schema approach requires a little bit of architecture but it removes the instability that you might be worried about.


One thing worth mentioning is that there is a difference between validating input on a syntax level (did I get all the required inputs) and input validation on a semantic level. Let's say you have a service called GetItem and you pass id = 3 the syntax checker will check for the presence of the id property and that it is a number. Then you need to check whether 3 actually exists.

So rather than returning invalid request (bad input) you might want to return no such item.

Halcyon
  • 57,230
  • 10
  • 89
  • 128
0

Your approach is functionally correct, as the && is short-circuited if the first term evaluates to false. Regarding stability, as you suspected, there is a small concern, related especially to code duplication, mainly you need to always pay care that both keys match the same string (it is appropriate to say this is a matter of code duplication).

One approach to this would be to define a function that does the check and returns the contents at the desired key if exist, like for example:

function arr(array $array, $key, $defaultValue=false) {
    return isset($arrray[$key]) ? $array[$key] : $defaultValue            
}

You pay a small performance penalty for calling a function (you can reduce it by removing the type hinting for the $array parameter), however you have a more stable code.

Usage example in your case:

if(arr($_POST, 'somedata') === 2)) {
    // do your stuff
}
Cristik
  • 30,989
  • 25
  • 91
  • 127
-1

We've been using this at work for some time now, going back years in code. It's fine to use since it first checks it the variable is actually there, and only then checks if it has a value.

Gerton
  • 676
  • 3
  • 14
-1

Your code snippet is correct.

    if (isset($_POST["somedata"]) && $_POST["somedata"] == 2)
            DoSomething();

I would highly encourage you to use the triple equals for your quality check. Check out How do the PHP equality (== double equals) and identity (=== triple equals) comparison operators differ? for more info on equality checks.

The triple equal means it needs to be an integer and not just a string, good practice to get into doing this.

Community
  • 1
  • 1
Jeff Sloyer
  • 4,899
  • 1
  • 24
  • 48
  • Aren't posted values always Strings? – kero Apr 10 '15 at 13:24
  • 1
    Yes, good point! I would check to see if its set then cast to an integer to make sure its the right type. – Jeff Sloyer Apr 10 '15 at 13:25
  • One of the PHP Key-features is, that it automatically parses the different types to the needed format (as long as they're compatible). So when I need a specific number (e.g. 2), it's more useful to write just `== 2`. When any number is required, then a check with `is_numeric()` will be enough. – Brainiac Apr 10 '15 at 13:53