Получите все ошибки/предупреждения 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/...)
Ответ 2
Здесь обсуждается и здесь (среди прочих), с второй ответ в последнем списке, используя сочетание set_error_handler()
с register_shutdown_function()
, являющееся хорошим решением.
Ответ 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