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


577

我已经看到@在某些功能前面使用了,如下所示:

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

这个符号有什么用?


3
RichieHindle和Aiden Bell都给出了正确的答案,但是由于我只能将一个答案设置为接受,因此我将选择第一个。抱歉,艾登
sv_in

1
抑制错误(虽然不错)在维护代码库时可能会导致错误... stackoverflow.com/a/7116175/282343
dennismonsewicz

Answers:



470

它抑制错误。

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

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

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


157
仅仅因为另一个答案就是得到了所有的爱而投票支持。
ajacian81

10
落后19位...来吧,人们快打败RichieHindle:P
艾登·贝尔

这个答案是第一个(与谁先回答一样)。
Mohd Abdul Mujib

227

@符号是错误控制运算符(也称为“静音”或“关机”运算符)。它使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;
}

58

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


34

就像之前已经回答过的那样:@运算符禁止显示PHP中的所有错误,包括通知,警告甚至严重错误。

但是: 请真的不要使用@运算符。

为什么?

好吧,因为当您使用@运算符进行错误抑制时,您根本不知道发生错误时从哪里开始。我已经对旧有代码感到“有趣”,其中一些开发@人员经常使用该运算符。尤其是在诸如文件操作,网络调用等情况下。在所有这些情况下,许多开发人员建议使用@操作员,因为当此处发生错误时,有时会超出范围(例如,第3方API可能无法访问等)。 )。

但是仍然不使用它有什么意义呢?让我们从两个角度看一下:

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

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

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


1
某些警告只能使用@可靠地抑制(例如,fopen(),其中任何预测结果的尝试都取决于竞争条件),如果您有代码以更整洁的方式处理错误条件,那么usuig @是正确的选择这样做特别有用,尤其是在您不返回text/html(或类似)返回客户端的情况下。(也许返回image/png或“ json”)
Jasen

1
您不应该禁止警告-它们表示您做错了什么。没有没有您无法正确检查或处理状态的比赛条件。
Ryan Rentfro '17

1
在某些地方,我的代码中包含以下内容。if( session_status() == PHP_SESSION_NONE ) session_start(); 这是我继承的旧版应用程序,在某些地方多次调用安装脚本,因此我必须进行测试。简单使用会出现什么问题(如果有)@session_start();
斯蒂芬·R

如果您知道自己在做什么,并且可以谨慎/策略地使用它,那么值得使用。@$this->stats['device_os'][$date][$creative_id][$device_id][$operating_system]['clicks']++;比在每个级别都具有isset检查并在不存在时填充它的方法要好得多。
dtbarne

1
给我一个很好的理由,为什么除了在某些地方读到它“纯属肮脏”之外可能会改变主意之外,添加十二行以上的代码并且不增加任何值,而只是降低代码的可读性和简洁性是值得做的。
dtbarne

7

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

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

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

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

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

这是为什么PHP首先具有这种@解决方法的一个完美示例。其他编程语言具有统一的异常处理来处理这种情况stackoverflow.com/questions/1087365
dreftymac

@dreftymac正是!
Sujeet Kumar

5

如果打开失败,则会生成E_WARNING级别的错误。您可以使用@禁止显示此警告。


5

@ 禁止显示错误消息。

它用于以下代码段:

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

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


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)@-运算符仅适用于表达式。

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

警告:-

当前,“ @”错误控制运算符前缀甚至将针对严重错误禁用错误报告,这些错误将终止脚本执行。除其他外,这意味着如果您使用“ @”抑制某个功能的错误,并且该功能不可用或输入错误,脚本将在那里死掉,而没有任何指示。



1

@禁止该函数引发的错误消息。fopen文件不退出时抛出错误。 @符号将使执行移至下一行,即使该文件不存在。我的建议是在开发PHP代码时不要在本地环境中使用此功能。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.