在 PHP 中使用 @ 运算符抑制错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/136899/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 21:36:42  来源:igfitidea点击:

Suppress error with @ operator in PHP

phpoperatorserror-suppression

提问by Mez

In your opinion, is it ever valid to use the @ operator to suppress an error/warning in PHP whereas you may be handling the error?

在您看来,使用 @ 运算符来抑制 PHP 中的错误/警告而您可能正在处理错误是否有效?

If so, in what circumstances would you use this?

如果是这样,你会在什么情况下使用它?

Code examples are welcome.

欢迎使用代码示例。

Edit: Note to repliers. I'm not looking to turn error reporting off, but, for example, common practice is to use

编辑:回复者请注意。我不打算关闭错误报告,但是,例如,通常的做法是使用

@fopen($file);

and then check afterwards... but you can get rid of the @ by doing

然后再检查......但你可以通过这样做来摆脱@

if (file_exists($file))
{
    fopen($file);
}
else
{
    die('File not found');
}

or similar.

或类似。

I guess the question is - is there anywhere that @ HAS to be used to supress an error, that CANNOT be handled in any other manner?

我想问题是 - 是否有任何地方可以使用 @ 来抑制错误,不能以任何其他方式处理?

采纳答案by Pawe? Hajdan

I would suppress the error and handle it. Otherwise you may have a TOCTOUissue (Time-of-check, time-of-use. For example a file may get deleted after file_exists returns true, but before fopen).

我会抑制错误并处理它。否则,您可能会遇到TOCTOU问题(检查时间、使用时间。例如,文件可能会在 file_exists 返回 true 之后但在 fopen 之前被删除)。

But I wouldn't just suppress errors to make them go away. These better be visible.

但我不会只是压制错误让它们消失。这些最好是可见的。

回答by Gerry

Note: Firstly, I realise 99% of PHP developers use the error suppression operator (I used to be one of them), so I'm expecting any PHP dev who sees this to disagree.

注意:首先,我意识到 99% 的 PHP 开发人员使用错误抑制运算符(我曾经是其中之一),所以我希望任何看到这一点的 PHP 开发人员不同意。

In your opinion, is it ever valid to use the @ operator to suppress an error/warning in PHP whereas you may be handling the error?

在您看来,使用 @ 运算符来抑制 PHP 中的错误/警告而您可能正在处理错误是否有效?

Short answer:
No!

简短的回答:
不!

Longer more correct answer:
I don't know as I don't know everything, but so far I haven't come across a situation where it was a good solution.

更长更正确的答案:
我不知道,因为我不知道一切,但到目前为止我还没有遇到过这是一个很好的解决方案的情况。

Why it's bad:
In what I think is about 7 years using PHP now I've seen endless debugging agony caused by the error suppression operator and have never come across a situation where it was unavoidable.

为什么不好:
在我使用 PHP 大约 7 年的时间里,我看到了由错误抑制运算符引起的无休止的调试痛苦,并且从未遇到过不可避免的情况。

The problem is that the piece of code you are suppressing errors for, may currently only cause the error you are seeing; however when you change the code which the suppressed line relies on, or the environment in which it runs, then there is every chance that the line will attempt to output a completely different error from the one you were trying to ignore. Then how do you track down an error that isn't outputting? Welcome to debugging hell!

问题是您正在抑制错误的代码段目前可能只会导致您看到的错误;但是,当您更改被抑制的行所依赖的代码或它运行的环境时,该行很可能会尝试输出与您试图忽略的错误完全不同的错误。那么你如何追踪一个没有输出的错误呢?欢迎来到调试地狱!

It took me many years to realise how much time I was wasting every couple of months because of suppressed errors. Most often (but not exclusively) this was after installing a third party script/app/library which was error free in the developers environment, but not mine because of a php or server configuration difference or missing dependency which would have normally output an error immediately alerting to what the issue was, but not when the dev adds the magic @.

我花了很多年才意识到我每几个月因为抑制错误而浪费了多少时间。大多数情况下(但并非唯一)这是在安装第三方脚本/应用程序/库之后,该脚本/应用程序/库在开发人员环境中没有错误,但不是我的,因为 php 或服务器配置差异或缺少通常会立即输出错误的依赖项提醒问题是什么,但不是当开发人员添加魔术@。

The alternatives (depending on situation and desired result):
Handle the actual error that you are aware of, so that if a piece of code is going to cause a certain error then it isn't run in that particular situation. But I think you get this part and you were just worried about end users seeing errors, which is what I will now address.

替代方案(取决于情况和预期结果):
处理您知道的实际错误,以便如果一段代码将导致某个错误,那么它就不会在该特定情况下运行。但是我认为您了解了这一部分,您只是担心最终用户会看到错误,这就是我现在要解决的问题。

For regular errors you can set up an error handler so that they are output in the way you wish when it's you viewing the page, but hidden from end users and logged so that you know what errors your users are triggering.

对于常规错误,您可以设置错误处理程序,以便在您查看页面时以您希望的方式输出,但对最终用户隐藏并记录,以便您知道用户触发了哪些错误。

For fatal errors set display_errorsto off (your error handler still gets triggered) in your php.ini and enable error logging. If you have a development server as well as a live server (which I recommend) then this step isn't necessary on your development server, so you can still debug these fatal errors without having to resort to looking at the error log file. There's even a trick using the shutdown functionto send a great deal of fatal errors to your error handler.

对于display_errors在 php.ini 中设置为关闭的致命错误(您的错误处理程序仍然被触发)并启用错误日志记录。如果您有一个开发服务器和一个实时服务器(我推荐),那么您的开发服务器上不需要这一步,因此您仍然可以调试这些致命错误,而不必求助于查看错误日志文件。甚至还有一个技巧可以使用关闭函数向错误处理程序发送大量致命错误。

In summary:
Please avoid it. There may be a good reason for it, but I'm yet to see one, so until that day it's my opinion that the (@) Error suppression operator is evil.

总之:
请避免它。可能有一个很好的理由,但我还没有看到一个,所以直到那天我认为 (@) 错误抑制运算符是邪恶的。

You can read my comment on the Error Control Operators pagein the PHP manual if you want more info.

如果您想了解更多信息,可以阅读在 PHP 手册中的错误控制运算符页面上的评论

回答by Jason Cohen

Yes suppression makes sense.

是的,压制是有道理的。

For example, the fopen()command returns FALSEif the file cannot be opened. That's fine, but it alsoproduces a PHP warning message. Often you don't want the warning -- you'll check for FALSEyourself.

例如,如果无法打开文件,该fopen()命令将返回FALSE。这很好,但它也会产生一条 PHP 警告消息。通常你不想要警告——你会FALSE自己检查。

In fact the PHP manualspecifically suggests using @ in this case!

事实上,PHP 手册特别建议在这种情况下使用 @!

回答by dirtside

If you don't want a warning thrown when using functions like fopen(), you can suppress the error but use exceptions:

如果您不希望在使用 fopen() 等函数时抛出警告,您可以抑制错误但使用异常:

try {
    if (($fp = @fopen($filename, "r")) == false) {
        throw new Exception;
    } else {
        do_file_stuff();
    }
} catch (Exception $e) {
    handle_exception();
}

回答by ashnazg

I NEVER allow myself to use '@'... period.

我从不允许自己使用 '@'... 句号。

When I discover usage of '@' in code, I add comments to make it glaringly apparent, both at the point of usage, and in the docblock around the function where it is used. I too have been bitten by "chasing a ghost" debugging due to this kind of error suppression, and I hope to make it easier on the next person by highlighting its usage when I find it.

当我在代码中发现“@”的用法时,我会添加注释以使其在使用点和使用它的函数周围的文档块中更加明显。由于这种错误抑制,我也被“追鬼”调试所困扰,我希望通过在我找到它时突出显示它的用法来使下一个人更容易。

In cases where I'm wanting my own code to throw an Exception if a native PHP function encounters an error, and '@' seems to be the easy way to go, I instead choose to do something else that gets the same result but is (again) glaringly apparent in the code:

如果我希望我自己的代码在原生 PHP 函数遇到错误时抛出异常,并且“@”似乎是一种简单的方法,我会选择做一些其他事情来获得相同的结果,但是(再次)在代码中非常明显:

$orig = error_reporting(); // capture original error level
error_reporting(0);        // suppress all errors
$result = native_func();   // native_func() is expected to return FALSE when it errors
error_reporting($orig);    // restore error reporting to its original level
if (false === $result) { throw new Exception('native_func() failed'); }

That's a lot more code that just writing:

这是更多的代码,只是编写:

$result = @native_func();

but I prefer to make my suppression need VERY OBVIOUS, for the sake of the poor debugging soul that follows me.

但我更愿意让我的抑制需要非常明显,为了跟随我的可怜的调试灵魂。

回答by Kent Fredric

Error suppression should be avoided unless you knowyou can handle all the conditions.

除非您知道自己可以处理所有情况,否则应避免错误抑制。

This may be much harder than it looks at first.

这可能比最初看起来要困难得多。

What you really should do is rely on php's "error_log" to be your reporting method, as you cannot rely on users viewing pages to report errors. ( And you should also disable php from displaying these errors )

您真正应该做的是依靠 php 的“error_log”作为您的报告方法,因为您不能依靠用户查看页面来报告错误。(并且您还应该禁止 php 显示这些错误)

Then at least you'll have a comprehensive report of all things going wrong in the system.

那么至少你会有一份关于系统中所有错误的综合报告。

If you really must handle the errors, you can create a custom error handler

如果您确实必须处理错误,则可以创建自定义错误处理程序

http://php.net/set-error-handler

http://php.net/set-error-handler

Then you could possibly send exceptions ( which can be handled ) and do anything needed to report weird errors to administration.

然后你可以发送异常(可以处理)并做任何需要向管理报告奇怪错误的事情。

回答by Your Common Sense

Most people do not understand the meaning of error message.
No kidding. Most of them.

大多数人不理解错误信息的含义。
不开玩笑。他们中的大多数。

They think that error messages are all the same, says "Something goes wrong!"
They don't bother to read it.
While it's most important part of error message - not just the fact it has been raised, but it's meaning. It can tell you whatis going wrong. Error messages are for help, not for bothering you with "how to hide it?" problem. That's one of the biggest misunderstandings in the newbie web-programming world.

他们认为错误信息都是一样的,都说“出问题了!”
他们懒得读。
虽然它是错误消息中最重要的部分 - 不仅仅是它被提出的事实,而是它的意义。它可以告诉你出了什么问题。错误消息是为了帮助,而不是为了“如何隐藏它”来打扰您。问题。这是新手网络编程世界中最大的误解之一。

Thus, instead of gagging error message, one should readwhat it says. It has not only one "file not found" value. There can be thousands different errors: permission denied, save mode restriction, open_basedir restrictionetc.etc. Each one require appropriate action. But if you gag it you'll never know what happened!

因此,与其扼杀错误信息,不如阅读它所说的内容。它不仅有一个“未找到文件”值。可能有数千种不同的错误:permission deniedsave mode restrictionopen_basedir restriction。每一项都需要采取适当的行动。但如果你把它塞住,你永远不会知道发生了什么!

The OP is messing up error reportingwith error handling, while it's very big difference!
Error handling is for user. "something happened" is enough here.
While error reporting is for programmer, who desperately need to know what certainly happened.

OP 将错误报告与错误处理混为一谈,但差异非常大!
错误处理是针对用户的。“发生了一些事情”就足够了。
虽然错误报告是为程序员准备的,他们迫切需要知道肯定发生了什么。

Thus, never gag errors messages. Both log itfor the programmer, and handle itfor the user.

因此,永远不要堵嘴错误消息。这两个记录它为程序员,处理它的用户。

回答by Milan Babu?kov

The only place where I really needed to use it is the eval function. The problem with eval is that, when string cannot be parsed due to syntax error, eval does not return false, but rather throws an error, just like having a parse error in the regular script. In order to check whether the script stored in the string is parseable you can use something like:

我真正需要使用它的唯一地方是 eval 函数。eval 的问题在于,当由于语法错误无法解析字符串时,eval 不会返回 false,而是抛出错误,就像在常规脚本中解析错误一样。为了检查存储在字符串中的脚本是否可解析,您可以使用以下内容:

$script_ok = @eval('return true; '.$script);

AFAIK, this is the most elegant way to do this.

AFAIK,这是最优雅的方法。

回答by Eric Lamb

Using @ is sometimes counter productive. In my experience, you should always turn error reporting off in the php.ini or call

使用@ 有时会适得其反。根据我的经验,您应该始终在 php.ini 中关闭错误报告或调用

error_reporting(0);

on a production site. This way when you are in development you can just comment out the line and keep errors visible for debugging.

在生产现场。这样,当您在开发中时,您只需注释掉该行并保持错误可见以进行调试。

回答by Enrico Murru

is there not a way to suppress from the php.ini warnings and errors? in that case you can debug only changing a flag and not trying to discovering which @ is hiding the problem.

有没有办法抑制 php.ini 的警告和错误?在这种情况下,您只能调试更改标志,而不是试图发现哪个 @ 隐藏了问题。