背景:
我的应用程序有三个环境:开发(本地)、测试/登台(产品服务器)、生产。该应用程序知道哪个是哪个。登台和生产的错误报告均为 0,因此永远不会显示错误。在开发中,我希望立即看到错误,并且希望看到它们发生的位置,所以不是在某些日志中,而是在代码的结果中。
但是,我不想看到我用
@
明确抑制的错误。我一直在使用 fsockopen
,当无法连接时会发出警告。我接受无连接,但不想看到错误。即使在开发中也没有。
显然,所有错误都会通过自定义错误处理程序,即使它们在代码中被抑制。
我的错误处理程序只有 4 个参数:errno、error、file、line。从这些我看不出错误最初是否被抑制。如果我可以看到那里,我可以选择是否打印错误(现在我总是这样做,如果 env=dev)。
有什么想法吗?或者也许如何完全忽略被抑制的错误(这样它们甚至不会到达自定义错误处理程序)?
set_error_handler
手册页中有对此的提示。
如果导致错误的语句是,则[
] 值将为 0 由 @ 错误控制运算符前置error_reporting()
当你使用错误控制运算符
@
时,发生的事情是这样的:
error_reporting(0)
上面有点令人困惑的引用是指
error_reporting
返回当前设置。如果您使用控制运算符抑制了错误,则调用 error_reporting()
将返回 0。
因此,如果您知道已将其设置为非零(即您正在报告一些错误)并且它返回零,则您知道错误已被抑制。
$php_errormsg
中找到它(如果 track_errors
在 true
中设置为 php.ini
)。
请注意,错误控制运算符会导致大量开销,因为它每次使用时都会更改错误报告级别两次。它会减慢你的脚本速度。
因此,在 PHP 8.0 中,您无法再仅通过检查 error_reporting() == 0 来判断错误/警告/通知等是否被抑制(使用 @)。
相反,它现在是一段相当长的带有常量的按位运算符,如下警告框中所述:https://www.php.net/manual/en/language.operators.errorcontrol.php
在自定义错误处理程序中,如果您想知道错误是否已使用 @ 符号抑制,请使用如下内容:
$PHP_8_SUPPRESSED = E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR | E_PARSE;
$er = error_reporting();
if ($er === 0 || $er === $PHP_8_SUPPRESSED) {
// do code because it was suppressed. Ex: return FALSE, etc.
}
在撰写本文时,
$PHP_8_SUPPRESSED
将等于整数值4437
,但最好不要对其进行硬编码,因为 PHP 的未来版本可能会更改这些常量值。
快速旁注:我真的希望他们刚刚创建了一个名为“E_SUPPRESSED_ERROR”的新常量或我们可以检查的类似内容。但遗憾的是他们没有!
error_reporting
@
。在极少数情况下,您想忽略错误,请使用空的 catch 块将此也添加到您的处理程序
// 错误已被 @ 运算符抑制 if (0 === error_reporting()) { return false;}