我已经看到在某些功能前面使用@,如下所示:
$fileHandle = @fopen($fileName, $writeAttributes);
这个符号的用途是什么?
里奇辛德尔和艾登·贝尔都给出了正确的答案,但由于我只能设定一个被接受的答案,所以我会选择第一个。对不起艾登
在维护代码库时,抑制错误(尽管很好)可能会导致错误。stackoverflow.com/a/7116175/282343
它会抑制错误消息-请参阅PHP手册中的错误控制操作符。
那是一个有点快的抽签!
是的,一直到第二个!我必须检查一下答案ID,看看谁先进来。)
@艾登:都死在尘土里了。8)
我有时间在发帖后更正我的禁止拼写…该死的是,你同时用一个链接进行了增强,愤怒:p
酷功能。为了避免undefined offset错误,不需要使用isset()。
它抑制错误。
参见手册中的错误控制操作员:
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 @...
因为另一个答案是得到所有的爱而被否决。
@Ajacian81-干杯!
19落后…来吧,伙计们,让我们打败里奇·辛德尔:P。
@艾登贝尔:你从第一天起就得到了我的选票。-)
这个答案是第一个(根据谁先回答的上下文)。
@符号是错误控制操作员(也称为"静默"或"关闭"操作员)。它使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错误处理程序,会发生什么情况:
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 @.
下面的代码示例说明了这一点:
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;
}
还要注意,尽管隐藏了错误,任何自定义错误处理程序(用set_error_handler设置)仍将被执行!
就像前面已经回答过的那样:@操作符禁止php中的所有错误,包括通知、警告甚至严重错误。
但是:请不要使用@操作符。
为什么?
好吧,因为当您使用@操作符进行错误抑制时,您根本不知道在发生错误时从何处开始。我已经对一些开发人员经常使用@操作符的遗留代码有了一些"乐趣"。尤其是在文件操作、网络调用等情况下,许多开发人员都建议使用@操作符,因为在这里发生错误时,有时会超出范围(例如,第三方API可能无法访问等)。
但不使用它有什么意义呢?让我们从两个角度来看看:
作为开发人员:当使用@时,我完全不知道从哪里开始。如果有成百上千的函数调用使用@,那么错误可能与everywhare类似。在这种情况下,无法进行合理的调试。即使这只是第三方的失误,那也很好,而且你做得很快。;-)此外,最好在错误日志中添加足够的详细信息,这样开发人员就可以轻松地决定日志条目是必须进一步检查的内容,还是仅仅是第三方失败超出了开发人员的范围。
作为用户:用户根本不关心错误的原因是什么。软件可以让他们工作,完成一项特定的任务,等等。他们不在乎是开发人员的错还是第三方的问题。特别是对于用户,我强烈建议记录所有错误,即使它们超出范围。也许你会注意到一个特定的API经常离线。你能做什么?你可以和你的API合作伙伴交谈,如果他们不能保持稳定,你应该寻找另一个合作伙伴。
简言之:你应该知道存在类似于@的东西(知识总是很好的),但不要使用它。许多开发人员(尤其是那些从其他人那里调试代码的开发人员)将非常感激。
某些警告只能使用@(例如fopen(),其中任何预测结果的尝试都受竞争条件的影响)可靠地抑制,如果您有代码以更整齐的方式处理错误条件,则使用@是正确的做法,这尤其有用,特别是如果您不将text/html返回到客户端。(可能返回image/png或"json")
你不应该压制警告——他们说你做错了什么。在任何竞赛条件下,您都不能正确地检查或处理状态。
在我的代码中有几个地方有以下内容。if( session_status() == PHP_SESSION_NONE ) session_start();这是我继承的一个传统应用程序,在有些地方安装脚本会被多次调用,所以我必须测试。如果使用@session_start();会有什么问题?
如果你知道你在做什么,并且谨慎地/战略性地使用它,那么它是值得使用的。@$this->stats['device_os'][$date][$creative_id][$device_id][$operating_system]['clicks']++;比在每个级别都进行ISSET检查并在不进行ISSET检查时将其填写好得多。
@不,不是。:-/我非常不同意。当然,在存在数组的子元素之前,必须检查父元素本身是否存在…你所做的一切都很肮脏,离成为最佳实践还很远。
给我一个很好的理由,为什么添加12行以上的代码而不添加任何值,但只降低代码的可读性和简洁性是值得做的,而不是你在某个地方读到它是"纯脏的",也许你可以改变我的想法。
假设我们没有使用"@"运算符,那么我们的代码如下所示:
$fileHandle = fopen($fileName, $writeAttributes);
如果我们试图打开的文件找不到怎么办?它将显示一条错误消息。
要抑制错误消息,我们使用"@"运算符,如下所示:
$fileHandle = @fopen($fileName, $writeAttributes);
这是一个很好的例子,说明为什么PHP首先有这种@解决方案。其他编程语言有统一的异常处理来处理这种场景stackoverflow.com/questions/1087365
如果打开失败,将生成E级警告错误。您可以使用@取消此警告。
@抑制错误信息。
它用于以下代码段:
@file_get_contents('http://www.exaple.com');
如果域"http://www.example.com"不可访问,将显示一个错误,但是对于@没有显示任何内容。
@抑制函数抛出的错误消息。fopen在文件不退出时抛出错误。@符号使执行移到下一行,即使文件不存在。我的建议是,在开发PHP代码时,不要在本地环境中使用它。
值得一提的是,在使用@You should be aware时,这里有一些指针,对于完整的运行视图,本文是:http://mstd.eu/index.php/2016/06/30/php-rapid-fire-what-is-the-symbol-used-for-in-php/
即使预先准备了@symbol,错误处理程序仍将被激发,这仅仅意味着设置了0的错误级别,这将必须在自定义错误处理程序中得到适当的处理。
在include前面加@会将include文件中的所有错误设置为错误级别0
PHP支持一个错误控制操作符:at符号(@)。在PHP中预先准备表达式时,该表达式可能生成的任何错误消息都将被忽略。
如果使用set_error_handler()设置了一个自定义错误处理程序函数,那么它仍然会被调用,但是这个自定义错误处理程序可以(并且应该)调用error_reporting(),当触发错误的调用前面有@时,它将返回0。
/* 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)一个简单的经验法则是:如果你能得到某个东西的值,你可以预先将@operator添加到它上面。例如,您可以将其前置到变量、函数和包含调用、常量等。不能将其前置到函数、类定义或条件结构(如if和foreach等)。
警告:
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.