isset($var) vs. @$var

2019-01-19 12:49发布

问题:

Is this an okay practice or an acceptable way to use PHP's error suppressing?

if (isset($_REQUEST['id']) && $_REQUEST['id'] == 6) {
  echo 'hi';
}

if (@$_REQUEST['id'] == 6) {
  echo 'hi';
}

EDIT:
I thought so too. The code (and idea) is from friend.
Thanks for proving me right. :)

回答1:

It's not a really good practice to use error suppressing. It's even not a good practice to use $_REQUEST at all. Just use isset() or !empty() or whatever, don't be lazy.

And one more thing, it is a "good practice" to close parenthesis when using isset() :)



回答2:

Suppressing the errors using @ only suppresses the display of the error, not the creation. So you get a small performance hit from the error if you don't check isset() first.



回答3:

No, it's not really an acceptable practice in my opinion. Apart from the fact that it looks sloppy, custom error handlers are still triggered even when using error suppression.

The manual offers more reasons to avoid its use altogether:

Currently the "@" error-control operator prefix will even disable error reporting for critical errors that will terminate script execution. Among other things, this means that if you use "@" to suppress errors from a certain function and either it isn't available or has been mistyped, the script will die right there with no indication as to why.



回答4:

i always use isset() as it's more specific. Also, i'd use a more specific superglobal variable, so use either $_POST, $_GET, $_SESSION. Being clear with your code avoids headaches later on :)

This is how i run my checks:

if(isset($_POST['id']) && $_POST['id'] == '6')
{
     // do stuff
}

This is pretty thorough checking, since it checks for an existance of a post, then whether my variable is part of the post, and finally if those two pass, it checks to see if my variable is equal to 6.



回答5:

Apart from being not a good practice, since @ can chew on really important errors down the call stack, performance penalty is minuscule.

Let's verify this with a benchmark.

<?php
error_reporting(-1);

$limit = 10000;

$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
    echo !isset($_GET['aaa']) ? '' : $_GET['aaa'];
}
$total = 1000000 * (microtime(true) - $start)/$limit;
echo "With isset: $total μs\n";

$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
    echo @$_GET['aaa'];
}
$total = 1000000 * (microtime(true) - $start)/$limit;
echo "With @: $total μs\n";

On my not-so-recent computer it outputs:

With isset: 0.295 μs
With @: 0.657 μs

μs is a millionth of a second. Both methods take close to half of a millionth of a second.

One could say, but what if I do this for hundreds or thousands times, will there will be any difference? If you have to do !isset() a million of times, then your program already spent about 0.3 second doing this! Which means that you shouldn't have been doing that in the first place.

Nevertheless, @ is a bad practice for anything more complex than a simple array, hence do not use it even if you know that performance difference is insignificant.