Получите все ошибки/предупреждения PHP/, которые произошли во время текущего запроса

Установка директивы display_errors на true (при установке error_reporting на E_ALL) печатает все ошибки, которые произошли во время текущего запроса, прежде чем удалять вывод PHP.

Поскольку я отправляю заголовки в свой PHP-код, я получаю еще несколько ошибок (отправка заголовка после отправки содержимого невозможна).

Теперь я хотел бы добавить сообщения об ошибках в конец моей страницы. Там я хотел бы показать все ошибки, которые произошли (до тех пор). К сожалению error_get_last возвращает только последнюю произошедшую ошибку.

Сначала я подумал, что set_error_handler может решить проблему, но я боюсь, что мой журнал ошибок больше не работает:

Важно помнить, что стандартный обработчик ошибок PHP полностью обойден для типов ошибок, указанных error_types, если функция обратного вызова не возвращает FALSE.

Кроме того:

Следующие типы ошибок не могут обрабатываться с помощью определенной пользователем функции: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING и большая часть E_STRICT, поднятых в файле, где вызывается set_error_handler().

Но, возможно, они также недоступны в error_get_last()

Итак, есть ли способ распечатать все ошибки после вывода сгенерированного контента?

Ответ 1

Обращаясь к вашей первой проблеме

Обработка ошибок будет работать до тех пор, пока:

функция обратного вызова возвращает FALSE

function myErrorHandler($error_level, $error_message, $error_file, $error_line, $error_context) {
    // Do your stuff here, e.g. saving messages to an array

    // Tell PHP to also run its error handler
    return false;
}

Одним из решений для хранения всех номеров ошибок (во внешнем массиве $error_list) может быть:

$error_list = array();

$myErrorHandler = function ($error_level, $error_message, $error_file, $error_line, $error_context) use (&$error_list) {
    $error_list[] = $error_level;
    // Tell PHP to also run its error handler
    return false;
};
// Set your own error handler
$old_error_handler = set_error_handler($myErrorHandler);

Другой подход - использовать Исключения. В комментариях к функция set_error_handler()

Также смотрите:

Ссылаясь на ваш второй вопрос:

Как уже говорилось, Egg: использование register_shutdown_function() - это способ, и код в ответе fooobar.com/questions/105439/... показывает вам, как.

Но имейте в виду, что

  • Регистрация функций shutdown и error-handling должна быть первой в коде (однажды я ошибся в файле конфигурации, который не обрабатывался корректно, так как после этого я зарегистрировал обработчик ошибок).
  • Ошибки анализа могут не обрабатываться корректно (см. комментарий в fooobar.com/questions/105439/...)

Ответ 3

Более полный пример, который улавливает все ошибки (исключения и ошибки), накачивает в файл журнала и запоминается в статическом классе; в конце вы запрашиваете статический класс, чтобы получить ошибку.

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

function customErrorHandler($errno, $errmsg, $filename, $linenum, $vars) {
    ErrorHandler($errno, $errmsg, $filename, $linenum, $vars, true);
}

function nullErrorHandler($errno, $errmsg, $filename, $linenum, $vars) {
    ErrorHandler($errno, $errmsg, $filename, $linenum, $vars, false);
}

function customExceptionHandler($exception) {
    if (is_a($exception, 'exceptionError')) {
        echo $exception->output();
    } else {
        ErrorHandler(E_ERROR, $exception->getMessage() . '(' . $exception->getCode() . ')', $exception->getFile(), $exception->getLine(), null, true);
    }
}

function nullExceptionHandler($exception) {
    if (is_subclass_of($exception, 'exceptionError')) {
        $exception->output();
    } else {
        ErrorHandler(E_WARNING, $exception->getMessage() . '(' . $exception->getCode() . ')', $exception->getFile(), $exception->getLine(), null, false);
    }
}


function ErrorHandler($errno, $errmsg, $filename, $linenum, $vars, $fatal) {
    $errortype = array (
            E_ERROR              => 'Error',
            E_WARNING            => 'Warning',
            E_PARSE              => 'Parsing Error',
            E_NOTICE             => 'Notice',
            E_CORE_ERROR         => 'Core Error',
            E_CORE_WARNING       => 'Core Warning',
            E_COMPILE_ERROR      => 'Compile Error',
            E_COMPILE_WARNING    => 'Compile Warning',
            E_DEPRECATED         => 'Deprecated',
            E_USER_ERROR         => 'User Error',
            E_USER_WARNING       => 'User Warning',
            E_USER_NOTICE        => 'User Notice',
            E_USER_DEPRECATED    => 'User Deprecated',
            E_STRICT             => 'Runtime Notice',
            E_RECOVERABLE_ERROR  => 'Catchable Fatal Error'
            );


    // Pushed into error log
    if (error_reporting() > 0) {
        $message = ': ' . $errmsg . ' in ' . $filename . ' on line ' . $linenum;
        error_log('PHP ' . $errortype[$errno] . $message);

        errorLogger::log($message);

        if ($fatal) {
            echo $errortype[$errno] . ': ' . $message;
            exit();
        }
    }
}


class errorLogger {

    private static $aErrors = array();

    // ******************* Timing functions *********************************

    public static function log($message) {
        self::$aErrors[] = $message;
    }

    public static function getErrors() {
        return self::$aErrors;
    }

}

Пример использования

// Custom error handler. Can cope with the various call mechanisms
$old_error_handler = set_error_handler('nullErrorHandler');
$old_exception_handler = set_exception_handler('nullExceptionHandler');

// Do your stuff
// *
// *
// *
// *
// *

$old_error_handler = set_error_handler('customErrorHandler');   // Set to 'nullErrorHandler' to allow it to continue
$old_exception_handler = set_exception_handler('customExceptionHandler');   // Set to 'nullExceptionHandler' to allow it to continue

// At end
$errors = errorLogger::getErrors();
foreach($errors as $errorMessage) {
    echo $errorMessage;
}

Ответ 4

Поймайте ошибки, когда вы идете, и выводите сообщения в конце.

<?php 
$errors = [];
try{    
  // code to test
} catch(\Exception $e) {
  $errors[] = $e->getMessage;
}
try{    
  // next bit of code to test
} catch(\Exception $e) {
  $errors[] = $e->getMessage;
}
...

// display all messages at the end
echo "\n<pre><code>\n";
print_r($errors);
echo "\n</code></pre>\n";

Ответ 5

 ini_set('display_errors', 1);
 ini_set('display_startup_errors', 1);
 error_reporting(E_ALL);

  or
   set your php.ini with this line:
   display_errors=on