检测(在自定义错误处理程序中)PHP 错误是否确实被 @

问题描述 投票:0回答:4

背景:

我的应用程序有三个环境:开发(本地)、测试/登台(产品服务器)、生产。该应用程序知道哪个是哪个。登台和生产的错误报告均为 0,因此永远不会显示错误。在开发中,我希望立即看到错误,并且希望看到它们发生的位置,所以不是在某些日志中,而是在代码的结果中。

但是,我不想看到我用

@
明确抑制的错误。我一直在使用
fsockopen
,当无法连接时会发出警告。我接受无连接,但不想看到错误。即使在开发中也没有。

显然,所有错误都会通过自定义错误处理程序,即使它们在代码中被抑制。

我的错误处理程序只有 4 个参数:errno、error、file、line。从这些我看不出错误最初是否被抑制。如果我可以看到那里,我可以选择是否打印错误(现在我总是这样做,如果 env=dev)。

有什么想法吗?或者也许如何完全忽略被抑制的错误(这样它们甚至不会到达自定义错误处理程序)?

php error-handling
4个回答
22
投票

set_error_handler
手册页中有对此的提示。

如果导致错误的语句是,则

[

error_reporting()
] 值将为 0 由 @ 错误控制运算符前置

当你使用错误控制运算符

@
时,发生的事情是这样的:

  1. 错误报告设置为 0(无错误) -
    error_reporting(0)
  2. 表达式被求值
  3. 错误报告设置回之前的值(即重新打开)

上面有点令人困惑的引用是指

error_reporting
返回当前设置。如果您使用控制运算符抑制了错误,则调用
error_reporting()
将返回 0。

因此,如果您知道已将其设置为非零(即您正在报告一些错误)并且它返回零,则您知道错误已被抑制。

如果您检测到被抑制的错误并想知道它是什么,您可以在变量

$php_errormsg
中找到它(如果
track_errors
true
中设置为
php.ini
)。

请注意,错误控制运算符会导致大量开销,因为它每次使用时都会更改错误报告级别两次。它会减慢你的脚本速度。


4
投票

适用于 PHP 8.0

因此,在 PHP 8.0 中,您无法再仅通过检查 error_reporting() == 0 来判断错误/警告/通知等是否被抑制(使用 @)。

相反,它现在是一段相当长的带有常量的按位运算符,如下警告框中所述:https://www.php.net/manual/en/language.operators.errorcontrol.php

修复 PHP 7.x 和 8.x

在自定义错误处理程序中,如果您想知道错误是否已使用 @ 符号抑制,请使用如下内容:

$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”的新常量或我们可以检查的类似内容。但遗憾的是他们没有!


1
投票

处理 php 错误的正确方法

  • 请勿使用
    error_reporting
  • 安装一个错误到异常处理程序(http://www.php.net/manual/en/class.errorexception.php,示例 1)并将所有 php“错误”转换为异常
  • 在主代码中,在适当的地方使用 try-catch
  • 安装异常处理程序来捕获主代码中未捕获的异常。该处理程序是输出和/或记录错误的唯一位置。
  • 请勿使用
    @
    。在极少数情况下,您想忽略错误,请使用空的 catch 块
  • 使用一些愚蠢的技巧来捕获“致命”错误。更好的是,联系 php 小组并尝试说服他们在脚本中处理“致命”错误。

0
投票

将此也添加到您的处理程序

// 错误已被 @ 运算符抑制 if (0 === error_reporting()) { return false;}

© www.soinside.com 2019 - 2024. All rights reserved.