PHP中@符号的用途是啥?

Posted

技术标签:

【中文标题】PHP中@符号的用途是啥?【英文标题】:What is the use of the @ symbol in PHP?PHP中@符号的用途是什么? 【发布时间】:2010-11-05 03:40:29 【问题描述】:

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

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

这个符号有什么用?

【问题讨论】:

RichieHindle 和 Aiden Bell 都给出了正确答案,但由于我只能将一个答案设置为已接受,我将选择第一个。对不起艾登 抑制错误(虽然很好)可能会在维护代码库时导致错误...***.com/a/7116175/282343 【参考方案1】:

@ 禁止显示错误消息。

在代码sn-ps中使用如:

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

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

【讨论】:

【参考方案2】:

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

【讨论】:

【参考方案3】:

@ 符号是error control operator(又名“沉默”或“闭嘴”运算符)。它使 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;

【讨论】:

echo @(1 / 0); 给了我DivisionByZeroError 我正在使用 php 8。也许是因为 DivisionByZeroError 是在 PHP 7 中添加的? @Omkar76 在编写此答案时,PHP5 中不存在此错误。 stfu 运算符的行为可能在 PHP8 中发生了变化。 但是docs 说它是在 7 中添加的。我认为它曾经只是一个警告。现在它抛出异常。哪个@显然无法压制。 @Omkar76 该页面上的 cmets 似乎表明它不再是一个警告,而是一个例外......这超出了@ 运算符的分数。【参考方案4】:

它会抑制错误消息 - 请参阅 PHP 手册中的 Error Control Operators。

【讨论】:

这有点快! 是的;降到第二!我必须检查 answer-id 看看谁先进来 :) 我有时间在发布后更正我的压制拼写......并且该死的你同时使用链接进行了增强愤怒:P 很酷的功能。它使isset()的使用变得不必要,以避免undefined offset错误。【参考方案5】:

它抑制错误。

参见手册中的Error Control Operators:

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

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

【讨论】:

这个答案是第一个(根据谁先回答的上下文)。【参考方案6】:

可能值得在此处添加一些提示,使用 @ 时您应该注意,要完整查看这篇文章:http://mstd.eu/index.php/2016/06/30/php-rapid-fire-what-is-the-symbol-used-for-in-php/

    1234563 >

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

【讨论】:

【参考方案7】:

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

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

为什么?

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

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

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

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

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

【讨论】:

某些警告只能使用 @ 可靠地抑制(例如 fopen(),其中任何预测结果的尝试都受制于竞争条件),如果您有代码来更整齐地处理错误条件那么使用@ 是正确的做法,这特别有用,特别是如果您没有将text/html(或类似的)返回给客户。 (可能返回 image/png 或 "json") 你不应该压制警告——它们是在说你做错了什么。没有无法正确检查或处理状态的竞争条件。 我的代码中有几个地方有以下内容。 if( session_status() == PHP_SESSION_NONE ) session_start();这是我继承的遗留应用程序,并且有多次调用设置脚本的地方,所以我必须测试。简单地使用@session_start(); 会有什么问题(如果有的话)? @dtbarne 不,不是。 :-/ 我非常不同意。当然,在存在数组的子元素之前,您必须检查父项本身是否存在……这只是您正在做的事情,而且远非最佳实践。 给我一个很好的理由,为什么添加 12 多行代码并且没有增加任何价值,但只会降低代码的可读性和简洁性,而不是你在某个地方读到它“很脏”也许你可以改变我的想法。【参考方案8】:

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

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

警告:-

目前“@”错误控制运算符前缀甚至会禁用 将终止脚本的严重错误的错误报告 执行。除其他外,这意味着如果您使用“@” 抑制某个功能的错误,或者它不可用 或者被打错了,脚本会死在那里,没有 说明原因。

【讨论】:

【参考方案9】:

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

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

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

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

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

【讨论】:

这是一个完美的例子,说明为什么 PHP 有这种@ 解决方法。其他编程语言都有统一的异常处理来处理这种场景***.com/questions/1087365 @dreftymac 没错!【参考方案10】:

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

【讨论】:

【参考方案11】:

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

【讨论】:

以上是关于PHP中@符号的用途是啥?的主要内容,如果未能解决你的问题,请参考以下文章

YAML 中管道符号的用途是啥?

PHP中cURL的用途是啥? [复制]

在客户端设置多个 PHP cookie 的实际用途是啥

OAuth中授权码的用途是啥

matlab 的用途是啥?

XML 在基于 Web 的应用程序中的用途是啥?