当前位置:  开发笔记 > 编程语言 > 正文

用PHP中的@运算符抑制错误

如何解决《用PHP中的@运算符抑制错误》经验,为你挑选了7个好方法。

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

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

欢迎使用代码示例.

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

@fopen($file);

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

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

或类似的.

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



1> Gerry..:

注意:首先,我意识到99%的PHP开发人员使用错误抑制操作符(我曾经是其中之一),所以我期待任何看到这个的PHP开发人员不同意.

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

简答:
不!

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

为什么它是坏的:
在我认为使用PHP大约7年的时候,我已经看到由错误抑制运算符引起的无休止的调试痛苦,并且从未遇到过无法避免的情况.

问题是,您正在抑制错误的代码段目前可能只会导致您看到的错误; 但是,当您更改受抑制的行所依赖的代码或其运行的环境时,该行有可能尝试从您尝试忽略的错误中输出完全不同的错误.那么如何追踪未输出的错误?欢迎调试地狱!

我花了很多年才意识到由于错误被压制,我每隔几个月浪费了多少时间.最经常(但不是唯一)这是在安装第三方脚本/应用程序/库之后,在开发人员环境中没有错误,但不是我的,因为php或服务器配置差异或缺少依赖性,这通常会立即输出错误提醒问题是什么,但不是当开发者添加魔法@时.

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

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

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

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

如果您想了解更多信息,可以在PHP手册的Error Control Operators页面上阅读我的评论.


这绝对是正确的.抑制错误是一个根本性的错误.使用您的错误处理程序,或使用异常,不要隐藏错误.
`-1`鹦鹉讽刺"是邪恶的"模因.避免使用内置语言功能而明确无视实际用例是货物崇拜编程的主要定义. - 特别是这种咆哮没有提到抑制错误实际上并没有消失.自定义错误处理程序仍然可以恢复它们(`set_error_handler("var_dump");`是scream扩展的惰性等价物).此外,这种过于宽泛的建议导致了普通的`isset()`通知抑制语法解决方法,这实际上可以阻碍调试(因为调试通知随后被无可挽回地抑制).
@mario"明确无视实际用例"......嗯......也许你没有读过"邪恶"的全文."可能有一个很好的理由,但我还没有看到一个,所以直到那天我认为(@)错误抑制操作符是邪恶的".我说我还没有找到这样的背景.看起来你对Op提出的问题有了答案,也许你可以考虑提交一个有更多空间来讨论你的观点的答案.
在检查索引值之前,您的代码不会检查索引是否存在.这将导致难以追踪问题,例如表单元素是重命名还是错误输入.不存在的索引意味着与表单元素不同的东西留空.此外,您不应该向最终用户显示错误.如果你只是在开发中遇到HTML/JSON问题,并认为留下它们没问题,这就是我们不同意的地方.典型执行路径上的通知通常表示无法处理您应该处理的条件.

2> Paweł Hajdan..:

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

但我不会只是压制错误以使它们消失.这些更好看.


问题在于,您最终会抑制您未预测的其他错误,然后花一整天的时间尝试追踪没有丢失任何错误的错误.在TOCTOU问题的罕见情况下,我认为抛出错误要好得多,因为最终用户不应该向最终用户显示PHP错误,但它仍然会让某人通过记录错误或显示错误来了解这种情况.如果脚本在开发环境中运行.错误抑制是隐藏问题的最佳方法.(例如,文件被删除:))
这很好,但是为了不被追捕和谋杀的爱,请检查正确的错误.我曾经花了太长时间追踪数据库问题 - 我看到了Close()失败,没有任何工作.最终我发现了最初的连接,并且"其他"检查基本上是空的.删除@,我立即能够辨别出连接凭据是坏的.

3> Jason Cohen..:

是抑制是有道理的.

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

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


不,它不能,还有其他失败条件,如"无权读取"或"文件繁忙".
但是,当然,首先检查file_exists($ file)可以避免这种情况吗?
这很好,直到fopen抛出你没想到的错误.您无法检查所有已知的错误情况?创建一个fopen包装函数.

4> dirtside..:

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

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


如果你抛出一个异常,那么你并不需要`else`,只需要`do_file_stuff()`.

5> ashnazg..:

我从不允许自己使用'@'...期间.

当我在代码中发现'@'的使用时,我添加了注释,使其在使用时和使用它的函数周围的docblock中都非常明显.由于这种错误抑制,我也被"追逐鬼"调试所困扰,我希望通过在找到它时突出显示它的用法,使下一个人更容易.

如果我希望自己的代码在本机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'); }

这只是编写的代码:

$result = @native_func();

但我更喜欢让我的抑制需要非常显着,为了跟随我的可怜的调试灵魂.



6> Kent Fredric..:

除非您知道可以处理所有条件,否则应该避免错误抑制.

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

你真正应该做的是依靠php的"error_log"作为你的报告方法,因为你不能依赖用户查看页面来报告错误.(你还应该禁用php显示这些错误)

那么至少你会得到一份关于系统中出现问题的综合报告.

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

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

然后,您可以发送异常(可以处理)并执行任何需要向管理报告奇怪错误的操作.



7> Your Common ..:

大多数人不理解错误信息的含义.
不开玩笑.大多数人.

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

因此,不应该呕吐错误信息,而应该阅读它所说的内容.它不仅有一个"找不到文件"的值.可以有上千种不同的错误:permission denied,save mode restriction,open_basedir restrictionetc.etc.每个人都需要采取适当行动 但如果你唠叨它,你永远不会知道发生了什么!

OP正在搞乱错误报告和错误处理,但这是非常大的差异!
错误处理是针对用户的."发生的事情"就足够了.
虽然错误报告是针对程序员的,但他们迫切需要知道发生了什么.

因此,永远不要唠叨错误消息.两者都记录给程序员,并为用户处理.

推荐阅读
赛亚兔备_393
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有