ChatGPT解决这个技术问题 Extra ChatGPT

What is the use of the @ symbol in PHP?

I have seen uses of @ in front of certain functions, like the following:

$fileHandle = @fopen($fileName, $writeAttributes);

What is the use of this symbol?

Both RichieHindle and Aiden Bell gave the right answer but since I can only set one answer as accepted, I will choose the first one. Sorry Aiden
Suppressing errors (although nice) could cause errors down the road when maintaining the codebase... stackoverflow.com/a/7116175/282343

U
Uwe Keim

It suppresses error messages — see Error Control Operators in the PHP manual.


That was a bit of a quick draw!
Yeah; down to the second! I had to check answer-id's to see who came in first :)
I had time to correct my suppress spelling after posting ... and damn you for enhancing with a link at the same time rages :P
Cool feature.. It makes the use of isset()'s unnecessary in order to avoid undefined offset errors.
g
gnat

It suppresses errors.

See Error Control Operators in the manual:

PHP supports one error control operator: the at sign (@). When prepended to an expression in PHP, any error messages that might be generated by that expression will be ignored. If you have set a custom error handler function with set_error_handler() then it will still get called, but this custom error handler can (and should) call error_reporting() which will return 0 when the call that triggered the error was preceded by an @...


This answer was the first one(In context with who answered it first).
S
Salman A

The @ symbol is the error control operator (aka the "silence" or "shut-up" operator). It makes PHP suppress any error messages (notice, warning, fatal, etc) generated by the associated expression. It works just like a unary operator, for example, it has a precedence and associativity. Below are some examples:

@echo 1 / 0;
// generates "Parse error: syntax error, unexpected T_ECHO" since 
// echo is not an expression

echo @(1 / 0);
// suppressed "Warning: Division by zero"

@$i / 0;
// suppressed "Notice: Undefined variable: i"
// displayed "Warning: Division by zero"

@($i / 0);
// suppressed "Notice: Undefined variable: i"
// suppressed "Warning: Division by zero"

$c = @$_POST["a"] + @$_POST["b"];
// suppressed "Notice: Undefined index: a"
// suppressed "Notice: Undefined index: b"

$c = @foobar();
echo "Script was not terminated";
// suppressed "Fatal error: Call to undefined function foobar()"
// however, PHP did not "ignore" the error and terminated the
// script because the error was "fatal"

What exactly happens if you use a custom error handler instead of the standard PHP error handler:

If you have set a custom error handler function with set_error_handler() then it will still get called, but this custom error handler can (and should) call error_reporting() which will return 0 when the call that triggered the error was preceded by an @.

This is illustrated in the following code example:

function bad_error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
    echo "[bad_error_handler]: $errstr";
    return true;
}
set_error_handler("bad_error_handler");
echo @(1 / 0);
// prints "[bad_error_handler]: Division by zero"

The error handler did not check if @ symbol was in effect. The manual suggests the following:

function better_error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
    if(error_reporting() !== 0) {
        echo "[better_error_handler]: $errstr";
    }
    // take appropriate action
    return true;
}

echo @(1 / 0); is giving me DivisionByZeroError I am using php 8. Maybe becuase DivisionByZeroError was added in PHP 7?
@Omkar76 no this error was present in PHP5 when this answer was written. The behavuor of stfu operator might have changed in PHP8.
But docs say it's added in 7. I think it used to be a warning only. Now it's throwing exception. Which @ is apparently unable to suppress.
@Omkar76 the comments on that page seems to indicate that it is no longer a warning but an exception... something that is beyond the score of @ operator.
n
nickf

Also note that despite errors being hidden, any custom error handler (set with set_error_handler) will still be executed!


A
Andreas

Like already some answered before: The @ operator suppresses all errors in PHP, including notices, warnings and even critical errors.

BUT: Please, really do not use the @ operator at all.

Why?

Well, because when you use the @ operator for error supression, you have no clue at all where to start when an error occurs. I already had some "fun" with legacy code where some developers used the @ operator quite often. Especially in cases like file operations, network calls, etc. Those are all cases where lots of developers recommend the usage of the @ operator as this sometimes is out of scope when an error occurs here (for example a 3rdparty API could be unreachable, etc.).

But what's the point to still not use it? Let's have a look from two perspectives:

As a developer: When @ is used, I have absolutely no idea where to start. If there are hundreds or even thousands of function calls with @ the error could be like everyhwere. No reasonable debugging possible in this case. And even if it is just a 3rdparty error - then it's just fine and you're done fast. ;-) Moreover, it's better to add enough details to the error log, so developers are able to decide easily if a log entry is something that must be checked further or if it's just a 3rdparty failure that is out of the developer's scope.

As a user: Users don't care at all what the reason for an error is or not. Software is there for them to work, to finish a specific task, etc. They don't care if it's the developer's fault or a 3rdparty problem. Especially for the users, I strongly recommend to log all errors, even if they're out of scope. Maybe you'll notice that a specific API is offline frequently. What can you do? You can talk to your API partner and if they're not able to keep it stable, you should probably look for another partner.

In short: You should know that there exists something like @ (knowledge is always good), but just do not use it. Many developers (especially those debugging code from others) will be very thankful.


Some warnings can only be reliably suppressed using @ (eg fopen(), where any attempt to predict the result is subject to a race condition), if you have code to handle the error condition in a tidier way then usuig @ is the right thing do do, this is especially useful especially if you aren't returning text/html (or similar) to the client. (maybe returning image/png or "json" )
You should not be suppressing warnings - they are stating you have done something wrong. There is no race condition in which you can not properly check or handle state.
I have the following in my code in a few places. if( session_status() == PHP_SESSION_NONE ) session_start(); It's a legacy app I inherited, and there are places where the setup script gets called multiple times, so I have to test. What, if any, problem would there be in simply using @session_start(); ?
@dtbarne No, it's not. :-/ I heavily disagree. Of course you have to check if the parent itself exists, before you exist a subelement of an array... It's just plain dirty what you are doing and far away from being a best-practice.
Give me a good reason why adding 12+ lines of code and adding no value but only reducing readability and brevity of the code is worth doing other than that you read somewhere some time that it's "plain dirty" and maybe you can change my mind.
P
Peter Mortensen

Suppose we haven't used the "@" operator then our code would look like this:

$fileHandle = fopen($fileName, $writeAttributes);

And what if the file we are trying to open is not found? It will show an error message.

To suppress the error message we are using the "@" operator like:

$fileHandle = @fopen($fileName, $writeAttributes);

This is a perfect example for why PHP has this kind of @ workaround in the first place. Other programming languages have uniform exception handling to deal with this kind of scenario stackoverflow.com/questions/1087365
@dreftymac Exactly !
A
Andrey

@ suppresses error messages.

It is used in code snippets like:

@file_get_contents('http://www.exaple.com');

If domain "http://www.exaple.com" is not accessible, an error will be shown, but with @ nothing is shown.


K
Kishor Singh

If the open fails, an error of level E_WARNING is generated. You may use @ to suppress this warning.


R
Ravi Hirani

PHP supports one error control operator: the at sign (@). When prepended to an expression in PHP, any error messages that might be generated by that expression will be ignored.

If you have set a custom error handler function with set_error_handler() then it will still get called, but this custom error handler can (and should) call error_reporting() which will return 0 when the call that triggered the error was preceded by an @.

<?php
/* Intentional file error */
$my_file = @file ('non_existent_file') or
    die ("Failed opening file: error was '$php_errormsg'");

// this works for any expression, not just functions:
$value = @$cache[$key];
// will not issue a notice if the index $key doesn't exist.

?>

Note:-

1) The @-operator works only on expressions.

2) A simple rule of thumb is: if you can take the value of something, you can prepend the @ operator to it. For instance, you can prepend it to variables, function and include calls, constants, and so forth. You cannot prepend it to function or class definitions, or conditional structures such as if and foreach, and so forth.

Warning:-

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.


t
twigg

It might be worth adding here there are a few pointers when using the @ you should be aware of, for a complete run down view this post: http://mstd.eu/index.php/2016/06/30/php-rapid-fire-what-is-the-symbol-used-for-in-php/

The error handler is still fired even with the @ symbol prepended, it just means a error level of 0 is set, this will have to be handled appropriately in a custom error handler. Prepending a include with @ will set all errors in the include file to an error level of 0


B
Barry

@ suppresses the error message thrown by the function. fopen throws an error when the file doesn't exit. @ symbol makes the execution to move to the next line even the file doesn't exists. My suggestion would be not using this in your local environment when you develop a PHP code.