Реализовать обработку ошибок в моем фреймворке - PullRequest
3 голосов
/ 25 сентября 2010

Я собираюсь приступить к реализации обработки ошибок в моем фреймворке и ищу несколько советов о том, как его построить.

Сначала позвольте мне объяснить, как в настоящее время создается мой фреймворк:

Imотделяя запуск инфраструктуры от запуска приложения, поэтому любые ошибки, вызванные запуском приложения, должны обрабатываться специально выделенным для этого классом.

Моя идея состоит в том, чтобы иметь класс Core_Error_exception, который установит ошибкусообщая E_ALL, так как мой фреймворк будет строгим в отношении ошибок для PHP 5.3 , тогда, когда я загружу свое приложение, я буду запускать функцию отключения в этом классе, чтобы восстановить все значения по умолчанию, измененные.

Что я собираюсь сделать, так это перехватить все ошибки E_*_NOTICE, а не E_*_ERROR, и затем перед запуском приложения я говорю классу прекратить захват ошибок, поскольку Application_Error_Exception будет следить за ошибками.

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

Тип класса, который я искал, выглядит примерно так:

class Core_Error_Exception
{
    var $previus_error_level,$captured_contents;

    private $stack_trace = array();

    public function Core_Error_Exception()
    {
        $this->previus_error_level = error_reporting(-1);
        set_error_handler(array($this,'_collect_error'));
        set_exception_handler(array($this,'_collect_error'));
        ob_start(array($this,'_capture'));
    }

    public function _collect_error($errno, $errstr, $errfile, $errline, $context)
    {
        $this->stack_trace[] = array(
            array('name' => 'Error ID:',    'value' => $errno),
            array('name' => 'Error String:','value' => $errstr),
            array('name' => 'Error File:',  'value' => $errfile),
            array('name' => 'Error Line:',  'value' => $errline),
            array('name' => 'Context PRE:', 'value' => $context)
        );
        var_dump($this->stack_trace);
    }

    /*
     * _capture is used to capture pre_bufferd content.
     */
    public function _capture($content,$bitfeild)
    {
        if($bitfeild & PHP_OUTPUT_HANDLER_START)
        {
            $this->captured_contents = $content;
        }

        if($bitfeild & PHP_OUTPUT_HANDLER_CONT)
        {
            $this->captured_contents .= $content;
        }

        if($bitfeild & PHP_OUTPUT_HANDLER_END)
        {
            $this->captured_contents .= $content;
        }
        return false;
    }
}

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

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

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

Обновлено : с текущим классом

Если срабатывают ошибки, такие как trigger_error ('test', XXX);Я хочу, чтобы иметь возможность отслеживать все ошибки, пока приложение не запустится или E_USER_ERROR не будет запущен.

Иногда я изо всех сил пытаюсь полностью понять систему ошибок PHP, и так далее, а иногда я запутываюсь в том, как его построить.его защита от падения.

Ответы [ 2 ]

3 голосов
/ 25 сентября 2010

Я не совсем уверен в том, что вы делаете, но самым простым способом было бы использовать вложенные блоки try, такие как

in Class Application:

    function run() {
        try {
            --do stuff
        } catch(AppException $e) {
            -- handle application-level exception
        }
        -- all other exceptions fall through


in Class Core:

    try {
        $core->init();
        $application->run(); <-- calls the above function
        $core->done();
    } catch(Exception $e) {
        --last chance exception handler
        --process exceptions the Application was unable to handle on its own
    }

, чтобы иметь возможность ловить php build-в случае ошибок или trigger_error событий, таким образом, вы также всегда должны устанавливать обработчик ошибок-исключений .

0 голосов
/ 25 сентября 2010

То, что у вас есть, выглядит довольно солидно.Вам нужно было бы добавить некоторую логику, чтобы при возникновении ошибки, которая закрывала ваш скрипт, вы сбрасывали вывод в буфер ob и отправляли все собранные данные в HTML-файл ошибки для отображения трассировки.Что-то вроде:

public function _collect_error($errno, $errstr, $errfile, $errline, $context)
{
    $this->stack_trace[] = array(
        array('name' => 'Error ID:',    'value' => $errno),
        array('name' => 'Error String:','value' => $errstr),
        array('name' => 'Error File:',  'value' => $errfile),
        array('name' => 'Error Line:',  'value' => $errline),
        array('name' => 'Context PRE:', 'value' => $context)
    );

    if($errno == E_USER_ERROR) {
        ob_clean();
        // Pass collected data to HTML template
        // Display HTML
        exit();
    }

    var_dump($this->stack_trace);
}

Я не уверен на 100%, что вы можете корректно восстановиться после фатальной ошибки, но из того, что вы говорите, вы просто ищете конкретные нефатальные ошибки, чтобы завершить обработку.

Кроме того, каково ваше намерение захватить буферизованный контент?Я бы предположил, что он либо отображается, если искомая ошибка никогда не обнаруживается, либо выдается, и отображается экран ошибки (почему я добавил ob_clean в функцию ошибки)?

...