Can I try/catch a warning?

I need to catch some warnings being thrown from some php native functions and then handle them.

Specifically:

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

It throws a warning when the DNS query fails.

try / catch doesn't work because a warning is not an exception.

I now have 2 options:

  • set_error_handler seems like overkill because I have to use it to filter every warning in the page (is this true?);

  • Adjust error reporting/display so these warnings don't get echoed to screen, then check the return value; if it's false , no records is found for hostname.

  • What's the best practice here?


    Set and restore error handler

    One possibility is to set your own error handler before the call and restore the previous error handler later with restore_error_handler() .

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

    You could build on this idea and write a re-usable error handler that logs the errors for you.

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

    Turning errors into exceptions

    You can use set_error_handler() and the ErrorException class to turn all php errors into exceptions.

    set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) {
        // 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) {
        // ...
    }
    

    The important thing to note when using your own error handler is that it will bypass the error_reporting setting and pass all errors (notices, warnings, etc.) to your error handler. You can set a second argument on set_error_handler() to define which error types you want to receive, or access the current setting using ... = error_reporting() inside the error handler.

    Suppressing the warning

    Another possibility is to suppress the call with the @ operator and check the return value of dns_get_record() afterwards. But I'd advise against this as errors/warnings are triggered to be handled, not to be suppressed.


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

    set_error_handler("warning_handler", E_WARNING);
    dns_get_record(...)
    restore_error_handler();
    
    function warning_handler($errno, $errstr) { 
    // do something
    }
    

    Be careful with the @ operator - while it suppresses warnings it also suppresses fatal errors. I spent a lot of time debugging a problem in a system where someone had written @mysql_query( '...' ) and the problem was that mysql support was not loaded into PHP and it threw a silent fatal error. It will be safe for those things that are part of the PHP core but please use it with care.

    bob@mypc:~$ php -a
    Interactive shell
    
    php > echo @something(); // this will just silently die...
    

    No further output - good luck debugging this!

    bob@mypc:~$ php -a
    Interactive shell
    
    php > echo something(); // lets try it again but don't suppress the error
    PHP Fatal error:  Call to undefined function something() in php shell code on line 1
    PHP Stack trace:
    PHP   1. {main}() php shell code:0
    bob@mypc:~$ 
    

    This time we can see why it failed.

    链接地址: http://www.djcxy.com/p/4516.html

    上一篇: 如何仅列出在两次提交之间更改的文件名?

    下一篇: 我可以尝试/发现警告吗?