0

Just curious why this would trigger a warning.
Note: query string param "test" is not included in the URL

//Notice: Undefined index: test 
if($_GET['test'] === 'somestring' && !empty($_GET['test'])) {
}

//Valid - No Warning.  Why is this Valid? Param 'test' was never given
if(!empty($_GET['test']) && $_GET['test'] === 'somestring') {
}

Is this because PHP evaluates from LEFT to RIGHT? And not the whole condition?

Daniel Li
  • 287
  • 2
  • 17
  • 2
    Most languages will "short-circuit" logic statements to avoid unnecessary computation. `&&` statements will stop at the first `false` and `||` statements will stop at the first `true`. In PHP you can use this to write otherwise-unsafe statements, like your second example. – Sammitch Jun 11 '18 at 21:07
  • @Sammitch "most" ? Interesting. Is there any language which evaluates all results irrespective of earlier results? – mehulmpt Jun 11 '18 at 21:08
  • @mehulmpt not specifically, no. – Sammitch Jun 11 '18 at 21:11
  • Possible duplicate of [Does PHP have short-circuit evaluation?](https://stackoverflow.com/questions/5694733/does-php-have-short-circuit-evaluation) – Nigel Ren Jun 11 '18 at 21:13
  • 2
    Yes VBA tries all statements before it continues. @mehulmpt – Andreas Jun 11 '18 at 21:14
  • @Sammitch For the second example, would you say this is "bad practice" and we should really be using two if statements instead? `if (!empty($_GET['test'])) { if ($_GET['test'] === 'somestring') { } }` – Daniel Li Jun 11 '18 at 22:42
  • 1
    Neither are better or worse practice, and they are equivalent statements. – Sammitch Jun 11 '18 at 22:52

3 Answers3

2
if(!empty($_GET['test']) && $_GET['test'] === 'somestring') {

Because you're using &&, if any condition is false, further conditions are not checked. Conditions are checked in the order they're written. Since here, first condition !empty($_GET['test']) is false, the next one does not evaluate hence no warning.

mehulmpt
  • 15,861
  • 12
  • 48
  • 88
1

In the first example:

//Notice: Undefined index: test 
    if($_GET['test'] === 'somestring' && !empty($_GET['test'])) {
}

you are trying to access the value of the variable first, before checking if it exists, which is what the second example is basically doing. After checking that it does not exist, it exits the conditional without testing the second part.

alanfcm
  • 663
  • 3
  • 15
0

Simply put, it comes down to operator precedence.
The documentation shows that && is evaluated left-to-right, which means the left part of the clause is evaluated first. In your case, that clause results in a warning. If you reversed your clause order, the empty() check would return false, then the logic would short circuit and stop evaluating.

Mr. Llama
  • 20,202
  • 2
  • 62
  • 115