614

我已经看到@了某些函数前面的用法,如下所示:

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

这个符号有什么用?

4

11 回答 11

669

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

于 2009-06-23T12:09:12.770 回答
492

它抑制错误。

请参阅手册中的错误控制运算符

PHP 支持一种错误控制运算符:at 符号 (@)。当附加到 PHP 中的表达式时,该表达式可能生成的任何错误消息都将被忽略。

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

于 2009-06-23T12:09:12.130 回答
245

@符号是错误控制运算符(又名“沉默”或“闭嘴”运算符)。它使 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;
}
于 2013-01-25T10:53:47.950 回答
59

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

于 2010-01-11T14:48:24.517 回答
44

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

但是: 请,真的不要使用@操作员。

为什么?

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

但是仍然不使用它有什么意义呢?我们从两个方面来看:

作为开发人员:什么时候@使用,我完全不知道从哪里开始。如果有数百甚至数千个带有@错误的函数调用可能就像everyhwere。在这种情况下,不可能进行合理的调试。即使它只是一个 3rdparty 错误 - 那也很好,你很快就完成了。;-) 此外,最好在错误日志中添加足够的详细信息,以便开发人员能够轻松地确定日志条目是必须进一步检查的内容,还是只是超出开发人员范围的第 3 方故障。

作为用户:用户根本不关心错误的原因是什么。软件可以让他们工作,完成特定任务等。他们不在乎这是开发人员的错还是第 3 方的问题。特别是对于用户,我强烈建议记录所有错误,即使它们超出范围。也许你会注意到某个特定的 API 经常离线。你能做什么?您可以与您的 API 合作伙伴交谈,如果他们无法保持稳定,您可能应该寻找另一个合作伙伴。

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

于 2016-04-27T14:35:44.603 回答
7

假设我们没有使用“@”运算符,那么我们的代码将如下所示:

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

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

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

$fileHandle = @fopen($fileName, $writeAttributes);
于 2015-03-22T05:35:24.437 回答
6

@抑制错误消息。

它用于以下代码片段:

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

如果无法访问域“http://www.exaple.com”,则会显示错误,但@不会显示任何内容。

于 2015-10-14T13:02:30.773 回答
5

如果打开失败,则会产生 E_WARNING 级别的错误。您可以使用 @ 来抑制此警告。

于 2013-08-12T10:41:56.713 回答
1

PHP 支持一种错误控制运算符: at 符号(@)。当附加到 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) @-operator 仅适用于表达式。

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

警告:-

目前,“@”错误控制运算符前缀甚至会禁用将终止脚本执行的严重错误的错误报告。除其他外,这意味着如果您使用“@”来抑制某个函数的错误,并且它不可用或输入错误,则脚本将在那里死掉,而没有说明原因。

于 2016-02-17T08:50:45.530 回答
1

可能值得在这里添加一些提示,使用 @ 时您应该注意,完整查看这篇文章: http: //mstd.eu/index.php/2016/06/30/php-快速射击-什么是-the-symbol-used-for-in-php/

  1. 即使前面有 @ 符号,错误处理程序仍然会被触发,这只是意味着设置了错误级别 0,这必须在自定义错误处理程序中进行适当处理。

  2. 在包含前面加上 @ 会将包含文件中的所有错误设置为错误级别 0

于 2016-06-30T14:35:28.863 回答
1

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

于 2018-08-10T09:21:34.180 回答