@符号在PHP中的用途是什么?

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

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

这个符号有什么用?

251049 次浏览

它抑制错误。

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

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.


?>

# EYZ0

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

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

警告:-

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

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

# EYZ1 # EYZ2

为什么?

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

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

当使用@时,我完全不知道从哪里开始。如果使用@调用了数百甚至数千个函数,错误可能会像everyhwere一样。在这种情况下不可能进行合理的调试。即使这只是一个第三方错误,也没关系,你很快就完成了。此外,最好在错误日志中添加足够的细节,这样开发人员就可以轻松地决定日志条目是必须进一步检查的,还是只是超出开发人员范围的第三方故障。

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

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

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

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

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

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