PHP: Как использовать set_error_handler() для правильной обработки всех ошибок, кроме уведомлений?

Я смущен тем, как правильно использовать set_error_handler(), а php documentation на самом деле не помогает уточнить.

Я хочу, чтобы он отправлял мне по электронной почте как можно больше ошибок, за исключением уведомлений.

У меня есть следующий код

<?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.
}

?>

Выше мой текущий параметр set_error_handler('globalErrorHandler', E_USER_WARNING);, который кажется неправильным в том, что он не охватывает ошибки trigger_error(). Я считаю, что это потому, что аргумент должен быть битовой маской вместо одного уровня ошибки, но я не уверен, как настроить его на максимальное количество ошибок/информации (кроме уведомлений). Я видел примеры, которые используют E_ALL, но на самом деле непосредственно вызывает какой-либо код, который включает в себя всю информацию об ошибках для ошибок.

Так или иначе, как я могу использовать set_error_handler, чтобы мой обработчик ошибок мог обрабатывать максимальный объем информации (чтобы я мог автоматически получать электронные письма, когда возникают такие проблемы, вместо того, чтобы просматривать журналы позже).

Ответ 1

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

Или, если вы действительно хотите все,

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

В качестве альтернативы вы можете просто установить его для использования всех ошибок и просто игнорировать его, если они не находятся в error_reporting (который вы установили на то же значение, что и указанная выше строка, также оператор @ работает тогда ):

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

Ответ 2

Оставьте второй параметр или передайте по умолчанию E_ALL | E_STRICT (все ошибки и ошибки строгости, не путайте побитовое OR здесь)

Кроме того, вы можете "поймать" Fatal errors, выполнив трюк register_shutdown_function() и error_get_last(), продемонстрированный здесь: Обработать фатальные ошибки в PHP с помощью register_shutdown_function()

Ответ 3

$error_type - это целое число, которое вы устанавливаете с помощью маскирования. Чтобы использовать обработчик ошибок для всего, кроме E_NOTICE, вы должны использовать одно из следующих значений:

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

Если вы хотите также исключить 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);

Обратите внимание на использование побитовых операторов "&", "~" и "|", см. PHP Побитовое руководство по эксплуатации.

Будьте осторожны, некоторые ошибки не будут подняты, если они произойдут до вашего вызова set_error_handler, или будут ошибки компилятора (маловероятно, но кто знает). См. PHP set_error_handler documentation.

Ответ 4

Как использовать запланированные задачи, чтобы сервер автоматически отправлял вам файлы журнала ошибок; вместо того, чтобы обрабатывать его таким образом в своем приложении..