我可以尝试/捕捉警告吗?

2022-08-30 05:56:37

我需要捕获一些从一些php本机函数抛出的警告,然后处理它们。

具体说来:

array dns_get_record  ( string $hostname  [, int $type= DNS_ANY  [, array &$authns  [, array &$addtl  ]]] )

当 DNS 查询失败时,它会引发警告。

try/catch不起作用,因为警告不是例外。

我现在有2个选择:

  1. set_error_handler似乎有点过分,因为我必须用它来过滤页面中的每个警告(这是真的吗?

  2. 调整错误报告/显示,使这些警告不会回显到屏幕上,然后检查返回值;如果是 ,则找不到主机名的记录。false

这里的最佳实践是什么?


答案 1

设置和还原错误处理程序

一种可能性是在调用之前设置自己的错误处理程序,并在以后使用 恢复以前的错误处理程序。restore_error_handler()

set_error_handler(function() { /* ignore errors */ });
dns_get_record();
restore_error_handler();

您可以基于这个想法构建并编写一个可重用的错误处理程序来记录错误。

set_error_handler([$logger, 'onSilencedError']);
dns_get_record();
restore_error_handler();

将错误转化为异常

您可以使用 和 类 将所有 php 错误转换为异常。set_error_handler()ErrorException

set_error_handler(function($errno, $errstr, $errfile, $errline) {
    // error was suppressed with the @-operator
    if (0 === error_reporting()) {
        return false;
    }
    
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});

try {
    dns_get_record();
} catch (ErrorException $e) {
    // ...
}

使用自己的错误处理程序时要注意的重要一点是,它将绕过设置并将所有错误(通知,警告等)传递给错误处理程序。您可以设置第二个参数来定义要接收的错误类型,或使用错误处理程序内部访问当前设置。error_reportingset_error_handler()... = error_reporting()

禁止显示警告

另一种可能性是用 @ 运算符抑制调用,并检查 after 的返回值。但我建议不要这样做,因为错误/警告被触发是为了被处理,而不是被抑制。dns_get_record()


答案 2

真正有效的解决方案是使用参数设置简单的错误处理程序,如下所示:E_WARNING

set_error_handler("warning_handler", E_WARNING);
dns_get_record(...)
restore_error_handler();

function warning_handler($errno, $errstr) { 
// do something
}

推荐