我看到过在某些函数前使用@,比如:

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

这个符号有什么用?


它抑制错误。

参见手册中的错误控制操作符:

PHP支持一个错误控制操作符:@符号。当在PHP中添加到表达式前时,该表达式可能生成的任何错误消息都将被忽略。 如果你已经用set_error_handler()设置了一个自定义错误处理函数,那么它仍然会被调用,但是这个自定义错误处理函数可以(并且应该)调用error_reporting(),当触发错误的调用前面有@…


它抑制错误消息-请参阅PHP手册中的错误控制操作符。


还要注意,尽管错误被隐藏,任何自定义错误处理程序(使用set_error_handler设置)仍将执行!


符号@是错误控制操作符(又名“沉默”或“关闭”操作符)。它使PHP抑制由关联表达式生成的任何错误消息(通知、警告、致命等)。它就像一个一元运算符,例如,它有优先级和结合性。下面是一些例子:

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

如果你使用自定义错误处理程序而不是标准的PHP错误处理程序,到底会发生什么:

如果已设置自定义错误处理程序函数 Set_error_handler()则它仍将被调用,但此自定义 错误处理程序可以(并且应该)调用error_reporting() 当触发错误的调用前面有@时返回0。

下面的代码示例说明了这一点:

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"

错误处理程序没有检查@符号是否有效。本手册建议:

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

如果打开失败,则生成E_WARNING级别的错误。你可以使用@来屏蔽这个警告。


假设我们没有使用“@”操作符,那么我们的代码看起来像这样:

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

如果我们试图打开的文件没有找到该怎么办?它将显示一条错误消息。

为了抑制错误消息,我们使用“@”操作符,例如:

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

@抑制错误信息。

它被用于如下代码片段:

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

如果域名“http://www.exaple.com”不可访问,则会显示错误,但没有显示@。


PHP支持一个错误控制操作符:@符号。当在PHP中添加到表达式前时,该表达式可能生成的任何错误消息都将被忽略。

如果您已经使用set_error_handler()设置了一个自定义错误处理函数,那么它仍然会被调用,但是这个自定义错误处理函数可以(并且应该)调用error_reporting(),当触发错误的调用前面带有@时,它将返回0。

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

?>

注意:-

1) @-操作符只作用于表达式。

2)一个简单的经验法则是:如果你可以取某个值,你可以在它前面加上@操作符。例如,可以将它前置到变量、函数和包含调用、常量等。不能将其前置到函数或类定义,或if和foreach等条件结构中。

警告:-

目前,“@”错误控制操作符前缀甚至将被禁用 将终止脚本的严重错误的错误报告 执行。除此之外,这意味着如果你使用“@”来 抑制某个函数的错误,或者该函数不可用 或者是打错了,脚本就会死,没有 说明原因。


就像之前已经有人回答的那样:@操作符抑制了PHP中的所有错误,包括通知、警告甚至严重错误。

但是:请不要使用@操作符。

Why?

好吧,因为当您使用@操作符来抑制错误时,当错误发生时,您完全不知道从哪里开始。在一些开发人员经常使用@操作符的遗留代码中,我已经获得了一些“乐趣”。特别是在文件操作、网络调用等情况下。这些都是许多开发人员推荐使用@操作符的情况,因为在这里发生错误时,@操作符有时超出了范围(例如,3rdparty API可能无法访问,等等)。

但为什么还不用呢?让我们从两个角度来看看:

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.

简而言之:你应该知道有@这样的东西存在(知识总是好的),但不要使用它。许多开发人员(尤其是那些来自他人的调试代码)将非常感激。


在这里可能值得添加的是,当使用@时,你应该注意一些指针,以完整地查看这篇文章:http://mstd.eu/index.php/2016/06/30/php-rapid-fire-what-is-the-symbol-used-for-in-php/

即使前面有@符号,错误处理程序仍然会被触发,这只是意味着设置了0的错误级别,这必须在自定义错误处理程序中进行适当处理。 在包含前加上@将把包含文件中的所有错误设置为0的错误级别


@抑制由函数抛出的错误消息。当文件未退出时,Fopen将抛出一个错误。符号使执行移动到下一行,即使文件不存在。我的建议是,当您开发PHP代码时,不要在本地环境中使用它。