PHP: Как мы регистрируем ошибки, которые происходят?

Например, если мы пытаемся добраться до некоторого API, но сбоя, или попытаться соединиться с нашей базой данных, но также и сбоем.

1
задан AleGore 2 March 2010 в 11:17
поделиться

6 ответов

Обработка ошибок php сложна, и есть много моментов, которые следует учитывать. В php у нас есть 3 типа ошибок:

  • Неустранимые ошибки, такие как вызов неопределенной функции. С ними мало что можно сделать. По крайней мере, установите display_errors = 0, log_errors = 1 в php.ini, чтобы они не отображались. А еще лучше написать петицию на bugs.php.net и потребовать полного устранения фатальных ошибок. Фатальные ошибки - это такой позор!

  • «Обычные» предупреждения и уведомления. Лучше всего преобразовать их в исключения, см. пример №1

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

0
ответ дан 3 September 2019 в 01:08
поделиться

Обратите внимание на ведение обширного журнала. Особенно на производительных системах.

  • Если вы просто пытаетесь обработать ошибки программирования, сначала вы должны поднять в коде флаг режима отладки. также очень полезна строгая обработка php. (устанавливается в php.ini или в настройках вашего apache vhost).

  • не пытайтесь отладить браузер / экран. как упоминалось в других сообщениях. установитеiplay_errors = 0 и log_errors = 1 в php ini (или установите его в настройках apache vhost)

  • , затем откройте окно консоли и выполните: tail -f

    в вашем php_error.log (путь задается в php .ini или настройками apache vhost)

  • , если вы используете фреймворк. используйте инструменты отладки фреймворка (cake)

  • , если у вас есть собственный фреймворк / или просто код. Вероятно, вам следует написать собственный класс обработчика исключений с возможностями отладки.

пример:

class MyFactory{
    public static function getLogger(){
        return new MyLogger();
    }
}

class ExampleExceptionWithLogging extends Exception{

    public __construct ($message=''){
        MyFactory::getLogger()->exception($message,$this->getTrace());
    }

}

class MyLogger{

    /**
    * @var string $logfile
    **/
    protected $logFile = '/var/log/php_error.log';

    /**
     * @param string $message
     * @param array $stackTrace
     **/
    public function exception($message,$stackTrace){
        $prefix = '[EXCEPTION] ';
        $this->writeOut($prefix.$message.' '.print_r($stackTrace,TRUE));
    }

    /** 
     * writes $value to given Logfile.
     * @param string $value
     * @param string|NULL $logFile FileName with full path
     */
    protected function writeOut($value,$logFile = NULL){
        if(is_null($logFile)){
                $logFile = $this->logFile;
        }
        error_log($value,3,$logFile);
    }
}

Использование: throw new ExampleExceptionWithLogging ('Образец сообщения');

0
ответ дан 3 September 2019 в 01:08
поделиться

Здесь есть три вопроса:

  1. перенаправление потока программы на обработку ошибки

  2. сбор информации, необходимой для разрешения ошибки

  3. предоставление этой информации соответствующим сторонам

Как уже говорили другие, (1) можно решить с помощью set_error_handler(), обратите внимание, что вы можете инстанцировать собственные клиентские ошибки в своем коде, например.

if (!$_SESSION['authenticated_user']) {
    $login="<a href='/login.php'>login</a>";
    trigger_error("Not authorized please $login", E_USER_WARNING);
}

Установленной практикой для сбора информации является трассировка стека - и она действительно доступна в PHP, однако это статический снимок состояния PHP кода в момент возникновения ошибки - если вы правильно протестировали свой код, то ошибка, скорее всего, не имеет никакого отношения к вашему PHP коду. Это хороший индикатор того, где вы должны попытаться исправить свой код, но не хороший индикатор того, что вам нужно исправить. Трассировка стека по-прежнему является полезным инструментом, но часто она была единственным инструментом для программ, которые выполнялись в течение длительного времени, кроме записи подробных логов того, что программа делала в преддверии ошибки. Помимо очевидного снижения производительности, продирание через несколько мегабайт журналов в поисках ошибки может быть похоже на поиск иголки в стоге сена. Однако, поскольку PHP-программы обычно просто генерируют веб-страницу при завершении работы, это дает возможность накапливать подробный журнал событий в переменной PHP, после чего вы можете выбрать запись переменной в файл только при возникновении ошибки.

Как и в большинстве других вещей в программировании, здесь есть компромисс - если произошла ошибка, которую вы не ожидали/планировали, откуда вы знаете, что ваша обработка ошибок сработает?

С точки зрения обеспечения доступности данных, вам, вероятно, не следует записывать их в базу данных - есть вероятность, что ваша программа могла не сработать из-за того, что база данных не работает должным образом - обработка ошибок должна быть очень, очень надежной. Хорошим подходом является сброс данных в файл с уникальным именем, что позволяет избежать проблем с нехваткой файлов, которые возникают при добавлении в объединенный файл журнала. Или используйте средства syslog. Можно даже отправить копию ошибки по электронной почте (но это опять же зависит от другой сложной подсистемы).

HTH

C.

0
ответ дан 3 September 2019 в 01:08
поделиться

Вы можете использовать обработку ошибок PHP. See set_error_handler

0
ответ дан 3 September 2019 в 01:08
поделиться

Есть несколько способов справиться с этим:

2
ответ дан 3 September 2019 в 01:08
поделиться

В PHP есть функция по умолчанию для регистрации ошибок; error_log

Пример с PHP.net:

<?php
// Send notification through the server log if we can not
// connect to the database.
if (!Ora_Logon($username, $password)) {
    error_log("Oracle database not available!", 0);
}

// Notify administrator by email if we run out of FOO
if (!($foo = allocate_new_foo())) {
    error_log("Big trouble, we're all out of FOOs!", 1,
               "operator@example.com");
}

// another way to call error_log():
error_log("You messed up!", 3, "/var/tmp/my-errors.log");
?>
0
ответ дан 3 September 2019 в 01:08
поделиться
Другие вопросы по тегам:

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