在您看来,使用@运算符来抑制PHP中的错误/警告是否有效,而您可能正在处理错误?
如果是这样,你会在什么情况下使用它?
欢迎使用代码示例.
编辑:回复者的注意事项.我不打算关闭错误报告,但是,例如,通常的做法是使用
@fopen($file);
然后检查......但是你可以通过这样做摆脱@
if (file_exists($file)) { fopen($file); } else { die('File not found'); }
或类似的.
我想问题是 - 是否有任何@HAS用于抑制错误,不能以任何其他方式处理?
注意:首先,我意识到99%的PHP开发人员使用错误抑制操作符(我曾经是其中之一),所以我期待任何看到这个的PHP开发人员不同意.
在您看来,使用@运算符来抑制PHP中的错误/警告是否有效,而您可能正在处理错误?
简答:
不!
更正确的回答:
我不知道,因为我不知道一切,但到目前为止,我没有遇到过这是一个很好的解决方案的情况.
为什么它是坏的:
在我认为使用PHP大约7年的时候,我已经看到由错误抑制运算符引起的无休止的调试痛苦,并且从未遇到过无法避免的情况.
问题是,您正在抑制错误的代码段目前可能只会导致您看到的错误; 但是,当您更改受抑制的行所依赖的代码或其运行的环境时,该行有可能尝试从您尝试忽略的错误中输出完全不同的错误.那么如何追踪未输出的错误?欢迎调试地狱!
我花了很多年才意识到由于错误被压制,我每隔几个月浪费了多少时间.最经常(但不是唯一)这是在安装第三方脚本/应用程序/库之后,在开发人员环境中没有错误,但不是我的,因为php或服务器配置差异或缺少依赖性,这通常会立即输出错误提醒问题是什么,但不是当开发者添加魔法@时.
替代方案(取决于情况和期望的结果):
处理您知道的实际错误,以便如果一段代码将导致某个错误,那么它不会在该特定情况下运行.但我认为你得到了这个部分而你只是担心最终用户会看到错误,这就是我现在要解决的问题.
对于常规错误,您可以设置错误处理程序,以便在查看页面时以您希望的方式输出错误处理程序,但是对最终用户隐藏并记录这些错误处理程序,以便您知道用户触发的错误.
对于display_errors
在php.ini中设置为关闭的致命错误(您的错误处理程序仍会被触发)并启用错误记录.如果你有一个开发服务器和一个实时服务器(我推荐),那么在开发服务器上不需要这一步,因此你仍然可以调试这些致命错误,而不必诉诸于查看错误日志文件.甚至还有一个技巧,使用shutdown函数向错误处理程序发送大量致命错误.
总结:
请避免它.可能有一个很好的理由,但我还没有看到一个,所以直到那天我认为(@)错误抑制操作符是邪恶的.
如果您想了解更多信息,可以在PHP手册的Error Control Operators页面上阅读我的评论.
我会压制错误并处理它.否则,您可能会遇到TOCTOU问题(检查时间,使用时间.例如,在file_exists返回true之后,但在fopen之前,文件可能会被删除).
但我不会只是压制错误以使它们消失.这些更好看.
是抑制是有道理的.
例如,如果无法打开文件,则fopen()
返回该命令FALSE
.这很好,但它也会产生一条PHP警告信息.通常你不想要警告 - 你会检查FALSE
自己.
事实上,PHP手册特别建议在这种情况下使用@!
如果您不希望在使用fopen()等函数时抛出警告,则可以抑制错误但使用异常:
try { if (($fp = @fopen($filename, "r")) == false) { throw new Exception; } else { do_file_stuff(); } } catch (Exception $e) { handle_exception(); }
我从不允许自己使用'@'...期间.
当我在代码中发现'@'的使用时,我添加了注释,使其在使用时和使用它的函数周围的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();
但我更喜欢让我的抑制需要非常显着,为了跟随我的可怜的调试灵魂.
除非您知道可以处理所有条件,否则应该避免错误抑制.
这可能比它最初看起来要困难得多.
你真正应该做的是依靠php的"error_log"作为你的报告方法,因为你不能依赖用户查看页面来报告错误.(你还应该禁用php显示这些错误)
那么至少你会得到一份关于系统中出现问题的综合报告.
如果您确实必须处理错误,则可以创建自定义错误处理程序
http://php.net/set-error-handler
然后,您可以发送异常(可以处理)并执行任何需要向管理报告奇怪错误的操作.
大多数人不理解错误信息的含义.
不开玩笑.大多数人.
他们认为错误信息都是一样的,说"出了问题!"
他们懒得读它.
虽然它是错误信息中最重要的部分 - 不仅仅是它已被提出的事实,而是它的含义.它可以告诉你出了什么问题.错误消息是为了帮助,而不是用"如何隐藏它"来打扰你?问题.这是新手网络编程世界中最大的误解之一.
因此,不应该呕吐错误信息,而应该阅读它所说的内容.它不仅有一个"找不到文件"的值.可以有上千种不同的错误:permission denied
,save mode restriction
,open_basedir restriction
etc.etc.每个人都需要采取适当行动 但如果你唠叨它,你永远不会知道发生了什么!
OP正在搞乱错误报告和错误处理,但这是非常大的差异!
错误处理是针对用户的."发生的事情"就足够了.
虽然错误报告是针对程序员的,但他们迫切需要知道发生了什么.
因此,永远不要唠叨错误消息.两者都记录给程序员,并为用户处理.