aka, Ищу общий обработчик ошибок (ΟΚ для коммерческого использования)
Я сомневаюсь, что я лучший программист PHP, поэтому, хотя у меня есть мой собственный общий обработчик ошибок для set_error_handler ()
, мне было интересно, что делают другие, и есть ли «лучший» (извините, если это звучит субъективно - я просто хочу выделить общие подходы (но даже самые лучшие Тег practice был удален из SO)).
Чтобы быть объективным, вот что я считаю необходимым. Пожалуйста, поправьте меня, если я ошибаюсь, и укажите мне хороший код, если вы согласны.
Я хочу получить как можно больше информации - не зная, в чем была ошибка.
поэтому, например, имеет смысл дамп стека вызовов.
и $ _ GET
, $ _ POST
и $ _ SESSION
.
и я хочу, чтобы стек вызовов и глобалы были красивыми -printed
Мне нужен какой-нибудь "текстовый" макет, а не CSS и причудливый JS для разворачивания / сворачивания информации. Моим пользователям, возможно, придется вырезать / вставить в электронную почту или даже распечатать и отправить по факсу.
Я хотел бы иметь возможность добавить заголовок моего собственного изобретения, желательно в качестве параметра, но я могу взломать код, если потребуется. Заголовок может включать версию программы, отметку времени и т. Д. (И, в моем случае, у меня есть контрольный трек, поэтому я могу включить несколько последних действий пользователя, которые привели к сбою).
некоторые пользователи могут разрешить мой код для автоматической отправки отчета по электронной почте некоторые могут пожелать предварительно просмотреть его и отправить его по электронной почте, а некоторые могут не захотеть, чтобы я отправлял электронное письмо.
Я предлагаю пойти по пути «Исключения».
Бросайте исключения, когда есть ошибка пользователя, и вы можете преобразовать ошибки php в исключения, например:
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");
Хотя этот тип поведения лучше всего работает в среде ООП. Если у вас нет единой точки входа (например, фронт-контроллера), вы также можете поймать свободные исключения с помощью этого:
function myException($exception)
{
echo "<b>Exception:</b> " , $exception->getMessage();
}
set_exception_handler('myException');
Простая отладка с исключениями будет выглядеть примерно так:
function parseException($e) {
$result = 'Exception: "';
$result .= $e->getMessage();
$trace = $e->getTrace();
foreach (range(0, 10) as $i) {
$result .= '" @ ';
if (!isset($trace[$i])) {
break;
}
if (isset($trace[$i]['class'])) {
$result .= $trace[$i]['class'];
$result .= '->';
}
$result .= $trace[$i]['function'];
$result .= '(); ';
$result .= $e->getFile() . ':' . $e->getLine() . "\n\n";
}
return $result;
}
Оттуда оценка глобалов и т. Д. - прогулка в парке. Вы можете найти вдохновение в панели инструментов отладки Symfony Framework, которая предлагает множество таких запросов.
Передача всей вашей обработки ошибок конечному пользователю не очень хорошая идея.
1) он раскрывает внутреннюю структуру вашего кода - ОК, поэтому он должен быть безопасным, даже если потенциальный злоумышленник имеет полный исходный код - но нет смысла делать их жизнь проще.
2) вы действительно верите, что конечный пользователь будет добросовестно копировать всю информацию и отправлять ее вам?
3) вы перегружаете пользователя большим количеством информации, которая его не волнует .
Способ, которым я их обрабатываю, состоит в том, чтобы собрать как можно больше информации на сервере (и записать ее в обычный файл при возникновении ошибки), а затем предоставить пользователю значимое сообщение об ошибке, включая простую ссылку на то, где я могу найти ошибку в журналы. Для крупномасштабных систем я бы также рекомендовал захватить отпечаток ошибки (например, последние 6 цифр хеша md5 трассировки стека), чтобы служба поддержки могла управлять и классифицировать несколько зарегистрированных инцидентов с одной и той же основной ошибкой.
Помните, что в PHP все данные очищаются по завершении скрипта. Если вы писали Java-приложение или программу на C, то вам действительно не нужно постоянно накапливать данные - поэтому единственными вариантами являются запись записей отладки / информации в журнал, а затем, как только возникает ошибка, пишите трассировку стека. в журнал. Но с помощью PHP для веб-страниц я обычно веду их журнал в переменной PHP, а затем записываю его в файл , когда возникает ошибка вместе со трассировкой стека (или когда скрипт завершается, и я ' установить код в коде, например, через сеанс, для анализа его поведения в сценариях без ошибок).
Сколько деталей вы записываете, зависит от вас - я обычно регистрирую все точки входа и выхода fn и любые запросы SQL.
, например,
function logit($msg)
{
global $runlog;
static $basetime;
if (!$basetime) $basetime=time();
$runlog.="+" . time()-$basetime . "s : " . $msg . "\n";
}