如何捕获PHP致命错误

我可以使用set_error_handler()来捕获大多数PHP错误,但它不适用于致命( E_ERROR )错误,例如调用一个不存在的函数。 是否有另一种方法来捕捉这些错误?

我正在尝试为所有错误调用mail() ,并且正在运行PHP 5.2.3。


使用register_shutdown_function记录致命错误,它需要PHP 5.2+:

register_shutdown_function( "fatal_handler" );

function fatal_handler() {
    $errfile = "unknown file";
    $errstr  = "shutdown";
    $errno   = E_CORE_ERROR;
    $errline = 0;

    $error = error_get_last();

    if( $error !== NULL) {
        $errno   = $error["type"];
        $errfile = $error["file"];
        $errline = $error["line"];
        $errstr  = $error["message"];

        error_mail(format_error( $errno, $errstr, $errfile, $errline));
    }
}

你将不得不定义error_mailformat_error函数。 例如:

function format_error( $errno, $errstr, $errfile, $errline ) {
    $trace = print_r( debug_backtrace( false ), true );

    $content = "
    <table>
        <thead><th>Item</th><th>Description</th></thead>
        <tbody>
            <tr>
                <th>Error</th>
                <td><pre>$errstr</pre></td>
            </tr>
            <tr>
                <th>Errno</th>
                <td><pre>$errno</pre></td>
            </tr>
            <tr>
                <th>File</th>
                <td>$errfile</td>
            </tr>
            <tr>
                <th>Line</th>
                <td>$errline</td>
            </tr>
            <tr>
                <th>Trace</th>
                <td><pre>$trace</pre></td>
            </tr>
        </tbody>
    </table>";
    return $content;
}

使用Swift Mailer编写error_mail函数。

也可以看看:

  • http://php.net/manual/en/reserved.variables.phperrormsg.php
  • http://php.net/manual/en/errorfunc.constants.php

  • 刚刚想出了这个解决方案(PHP 5.2.0+):

    function shutDownFunction() { 
        $error = error_get_last();
        // fatal error, E_ERROR === 1
        if ($error['type'] === E_ERROR) { 
            //do your stuff     
        } 
    }
    register_shutdown_function('shutDownFunction');
    

    在http://www.php.net/manual/en/errorfunc.constants.php中定义了不同的错误类型


    PHP不提供从致命错误中捕获和恢复的常规手段。 这是因为处理通常不应该在致命错误后被恢复。 匹配输出缓冲区的字符串(正如PHP.net上描述的原始文章所建议的那样)绝对不适合。 这根本不可靠。

    从错误处理程序方法中调用mail()函数也被证明是有问题的。 如果你有很多错误,你的邮件服务器将被加载工作,并且你可能会发现自己的一个粗糙的收件箱。 为避免这种情况,您可能会考虑运行cron以定期扫描错误日志并相应地发送通知。 您可能还想研究系统监控软件,如Nagios。


    谈谈关于注册关机功能的一点:

    确实,你可以注册关机功能,这是一个很好的答案。

    这里的要点是,我们通常不应该尝试从致命错误中恢复,特别是不要使用正则表达式对输出缓冲区进行恢复。 我回应了接受的答案,该答案与php.net上的建议有关,后者已被更改或删除。

    该建议是在异常处理期间针对输出缓冲区使用正则表达式,并且在发生致命错误(通过匹配您所期望的任何配置的错误文本来检测)时,尝试执行某种恢复或继续处理。 这不会是一个推荐的做法(我相信这也是为什么我也找不到最初的建议,我可以忽略它,或者PHP社区将它击落)。

    值得注意的是,在输出缓冲回调被调用之前,较新版本的PHP(大约5.1)似乎更早地调用了关闭函数。 在版本5和更早版本中,该顺序是相反的(输出缓冲回调之后是关闭功能)。 此外,由于约5.0.5(这比问题的5.2.3版本早得多),因此在调用已注册的关闭函数之前卸载对象,因此您将无法依赖内存中的对象执行操作很多东西。

    所以注册一个关闭函数没有问题,但是应该由关闭函数执行的任务可能仅限于一些轻微的关闭过程。

    这里关键的一点是,任何人在这个问题上磕磕绊绊,并在最初接受的答案中看到建议时,都只是一些智慧的话语。 不要对输出缓冲区进行regex。

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

    上一篇: How do I catch a PHP Fatal Error

    下一篇: Is there a static way to throw exception in php