PHP:如何使用 set_error_handler() 正确处理除通知之外的所有错误?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6217994/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 23:40:55  来源:igfitidea点击:

PHP: How to use set_error_handler() to properly deal with all errors except notices?

phperror-handling

提问by Kzqai

I'm confused about how to use set_error_handler() properly, and the php documentationisn't really helping to clarify.

我对如何正确使用 set_error_handler() 感到困惑,而且php 文档并没有真正帮助澄清。

I want it to email me as many errors as possible, with the exception of notices.

我希望它通过电子邮件向我发送尽可能多的错误,通知除外。

I have the following code

我有以下代码

<?php

if (TRAP_ERRORS) { 
// True on production, false in development, where errors are just echoed out.
    set_exception_handler('globalExceptionHandler');
    set_error_handler('globalErrorHandler', E_USER_WARNING);
}

function globalExceptionHandler($e) {
    //log and email stuff here
}

function globalErrorHandler($errno, $errstr, $errfile, $errline) {
    switch ($errno) {
        case E_NOTICE:
        case E_USER_NOTICE:
            $errors = "Notice";
            break;
        case E_WARNING:
        case E_USER_WARNING:
            $errors = "Warning";
            break;
        case E_ERROR:
        case E_USER_ERROR:
            $errors = "Fatal Error";
            break;
        default:
            $errors = "Unknown Error";
            break;
    }

    error_log(sprintf("PHP %s:  %s in %s on line %d", $errors, $errstr, $errfile, $errline));
    $msg = "ERROR: [$errno] $errstr\r\n".
        "$errors on line $errline in file $errfile\r\n";

    sendErrorEmail($msg);
    showErrorPage();

    exit(1);
}

function sendErrorEmail($p_errorMsg) {
    // Parse and sent out the error email...
}

function showErrorPage() {
    // Redirect to an error page.
}

?>

Above is my current setting set_error_handler('globalErrorHandler', E_USER_WARNING);, which seems to be wrong in that it doesn't cover trigger_error() errors. I believe that is because the argument is supposed to be a bitmask instead of just a single error level, but I am not sure how to set it to work for the maximum number of errors/information (except notices). I've seen examples that use E_ALL, but that actually directly causes any code that includes the global error handler stuff to error for me.

以上是我当前的设置set_error_handler('globalErrorHandler', E_USER_WARNING);,这似乎是错误的,因为它不包括 trigger_error() 错误。我相信这是因为该参数应该是位掩码,而不仅仅是单个错误级别,但我不确定如何将其设置为适用于最大数量的错误/信息(通知除外)。我见过使用 的示例E_ALL,但这实际上直接导致任何包含全局错误处理程序内容的代码对我来说出错。

So anyway, how do I use set_error_handler so that the maximum amount of information can be handled by my custom error handler (so that I can get automatic emails directly when such problems occur, instead of having to review the logs later).

所以无论如何,我如何使用 set_error_handler 以便我的自定义错误处理程序可以处理最大量的信息(这样我可以在发生此类问题时直接收到自动电子邮件,而不必稍后查看日志)。

采纳答案by Wrikken

set_error_handler('some_handler',E_ALL & ~E_NOTICE & ~E_USER_NOTICE);

Or, if you really want all,

或者,如果你真的想要所有,

set_error_handler('some_handler',-1 & ~E_NOTICE & ~E_USER_NOTICE);

Alternatively, you can just set it to use all errors, and just ignore it if they're not in error_reporting(which you set to the same value as the above line, also, the @operator works then):

或者,您可以将其设置为使用所有错误,如果它们不在,则忽略它error_reporting(您将其设置为与上一行相同的值,@然后操作符工作):

....
if(!($errno & error_reporting())) return true;
switch($errno){
....

回答by Halcyon

Leave out the second parameter or pass in the default E_ALL | E_STRICT(all errors AND strictness errors, don't be confused by the bitwise ORhere)

省略第二个参数或传入默认值E_ALL | E_STRICT(所有错误和严格性错误,不要被OR这里的按位混淆)

Additionally you can 'catch' Fatal errorsby doing a register_shutdown_function()and error_get_last()trick demonstrated here: Handle fatal errors in PHP using register_shutdown_function()

此外,你可以“抓”Fatal errors做一个register_shutdown_function()error_get_last()伎俩这里演示:使用register_shutdown_function在PHP拉手致命错误()

回答by MGwynne

The $error_typeis an integer which you set using masking. To use an error handler for everything except E_NOTICE you'd use one of the following:

$error_type是你设置使用屏蔽的整数。要对除 E_NOTICE 之外的所有内容使用错误处理程序,您可以使用以下方法之一:

set_error_handler('globalErrorHandler', E_ALL ^ E_NOTICE);
set_error_handler('globalErrorHandler', E_ALL & ~E_NOTICE);

If you want to also exclude E_USER_NOTICE then:

如果您还想排除 E_USER_NOTICE,则:

set_error_handler('globalErrorHandler', E_ALL ^ (E_NOTICE | E_USER_NOTICE));
set_error_handler('globalErrorHandler', E_ALL & ~E_NOTICE & ~E_USER_NOTICE);

Note the use of the bitwise operators "&", "~" and "|", see PHP Bitwise operator manual.

请注意按位运算符“&”、“~”和“|”的使用,请参阅PHP 按位运算符手册

Be careful, some errors will not be picked up if they occur before your set_error_handler call, or are compiler errors (unlikely, but who knows). See PHP set_error_handler documentation.

请注意,如果某些错误发生在您的 set_error_handler 调用之前,或者是编译器错误(不太可能,但谁知道),它们将不会被发现。请参阅PHP set_error_handler 文档

回答by Faisal Nasim

How about using scheduled tasks to let the server send you the error log files automatically; instead of handling it this way within your application..

如何使用计划任务让服务器自动向您发送错误日志文件;而不是在您的应用程序中以这种方式处理它..