Великая унифицированная теория обработки ошибок PHP

aka, Ищу общий обработчик ошибок (ΟΚ для коммерческого использования)

Я сомневаюсь, что я лучший программист PHP, поэтому, хотя у меня есть мой собственный общий обработчик ошибок для set_error_handler () , мне было интересно, что делают другие, и есть ли «лучший» (извините, если это звучит субъективно - я просто хочу выделить общие подходы (но даже самые лучшие Тег practice был удален из SO)).

Чтобы быть объективным, вот что я считаю необходимым. Пожалуйста, поправьте меня, если я ошибаюсь, и укажите мне хороший код, если вы согласны.

  • Я хочу получить как можно больше информации - не зная, в чем была ошибка.

  • поэтому, например, имеет смысл дамп стека вызовов.

  • и $ _ GET , $ _ POST и $ _ SESSION .

  • и я хочу, чтобы стек вызовов и глобалы были красивыми -printed

  • Мне нужен какой-нибудь "текстовый" макет, а не CSS и причудливый JS для разворачивания / сворачивания информации. Моим пользователям, возможно, придется вырезать / вставить в электронную почту или даже распечатать и отправить по факсу.

  • Я хотел бы иметь возможность добавить заголовок моего собственного изобретения, желательно в качестве параметра, но я могу взломать код, если потребуется. Заголовок может включать версию программы, отметку времени и т. Д. (И, в моем случае, у меня есть контрольный трек, поэтому я могу включить несколько последних действий пользователя, которые привели к сбою).

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

23
задан sepehr 7 December 2013 в 11:28
поделиться

2 ответа

Я предлагаю пойти по пути «Исключения».

Бросайте исключения, когда есть ошибка пользователя, и вы можете преобразовать ошибки 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, которая предлагает множество таких запросов.

28
ответ дан 29 November 2019 в 01:51
поделиться

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

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";
}
3
ответ дан 29 November 2019 в 01:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: