Вопрос

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

Это было полезно?

Решение

Одна вещь, которую следует добавить к тому, что уже было сказано, - это то, что крайне важно, чтобы вы записывали любые ошибки в своем веб-приложении в журнал.Таким образом, как предлагает Джефф "Coding Horror" Этвуд, вы будете знать, когда у ваших пользователей возникают проблемы с вашим приложением (вместо того, чтобы "спрашивать их, что не так").

Для этого я рекомендую следующий тип инфраструктуры:

  • Создайте "аварийную" таблицу в своей базе данных и набор классов-оболочек для сообщения об ошибках.Я бы рекомендовал установить категории для сбоев ("блокировка", "безопасность", "Ошибка / предупреждение PHP" (vs exception) и т.д.).
  • Во всем вашем коде обработки ошибок обязательно укажите ошибку.Выполнение этого последовательно зависит от того, насколько хорошо вы создали API (шаг выше) - это должно быть тривиальный для записи сбоев, если все сделано правильно.

Дополнительный кредит:иногда ваши сбои будут происходить на уровне базы данных:т. е.Сервер базы данных отключен и т.д.Если это так, ваша инфраструктура регистрации ошибок (выше) выйдет из строя (вы не сможете зарегистрировать сбой в базе данных, потому что журнал пытается выполнить запись в базу данных).В этом случае я бы написал логику отработки отказа в вашем классе-оболочке Crash для любого

  • отправьте электронное письмо администратору И / ИЛИ
  • запишите подробности сбоя в обычный текстовый файл

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

Другие советы

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

function exceptions_error_handler($severity, $message, $filename, $lineno) {
  if (error_reporting() == 0) {
    return;
  }
  if (error_reporting() & $severity) {
    throw new ErrorException($message, 0, $severity, $filename, $lineno);
  }
}
set_error_handler('exceptions_error_handler');
error_reporting(E_ALL ^ E_STRICT);

Однако есть несколько случаев, когда код специально разработан для работы с ошибками.Например, в schemaValidate способ получения DomDocument выдает предупреждения при проверке документа.Если вы преобразуете ошибки в исключения, проверка прекратится после первого сбоя.Иногда это то, что вы хотите, но при проверке документа вы действительно можете захотеть ВСЕ неудачи.В этом случае вы можете временно установить обработчик ошибок, который собирает ошибки.Вот небольшой фрагмент, который я использовал для этой цели:

class errorhandler_LoggingCaller {
  protected $errors = array();
  function call($callback, $arguments = array()) {
    set_error_handler(array($this, "onError"));
    $orig_error_reporting = error_reporting(E_ALL);
    try {
      $result = call_user_func_array($callback, $arguments);
    } catch (Exception $ex) {
      restore_error_handler();
      error_reporting($orig_error_reporting);
      throw $ex;
    }
    restore_error_handler();
    error_reporting($orig_error_reporting);
    return $result;
  }
  function onError($severity, $message, $file = null, $line = null) {
    $this->errors[] = $message;
  }
  function getErrors() {
    return $this->errors;
  }
  function hasErrors() {
    return count($this->errors) > 0;
  }
}

И пример использования:

$doc = new DomDocument();
$doc->load($xml_filename);
$validation = new errorhandler_LoggingCaller();
$validation->call(
  array($doc, 'schemaValidate'),
  array($xsd_filename));
if ($validation->hasErrors()) {
  var_dump($validation->getErrors());
}

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

Как правило, вы можете использовать блок Try-Catch для обработки ошибок

try
{
    // Code that may error
}
catch (Exception $e)
{
    // Do other stuff if there's an error
}

Если вы хотите остановить появление сообщения об ошибке или предупреждения на странице, вы можете префиксить вызов знаком @ вот так.

 @mysql_query($query);

Однако с запросами, как правило, рекомендуется делать что-то подобное, чтобы у вас было лучшее представление о том, что происходит.

@mysql_query($query)
    or die('Invalid query: ' . mysql_error() . '<br />Line: ' . __LINE__ . '<br />File: ' . __FILE__ . '<br /><br />');

Вам следует использовать обработку ошибок в тех случаях, когда у вас нет явного контроля над данными, над которыми работает ваш скрипт.Я склонен часто использовать его, например, в таких местах, как проверка формы.Знание того, как определять места в коде, подверженные ошибкам, требует некоторой практики:Некоторые распространенные из них возникают после вызовов функций, возвращающих значение, или при обработке результатов запроса к базе данных.Вы никогда не должны предполагать, что возврат из функции будет таким, как вы ожидаете, и вы должны быть уверены, что кодируете в ожидании.Вам не обязательно использовать блоки try / catch, хотя они полезны.Часто вы можете обойтись простой проверкой if / else.

Обработка ошибок идет рука об руку с методами безопасного кодирования, поскольку существует множество "ошибок", которые не приводят к простому сбою вашего скрипта.хотя addedbytes не занимается строго обработкой ошибок как таковой, в нем есть хорошая серия из 4 статей о некоторых основах безопасного программирования на PHP, которые вы можете найти ЗДЕСЬ.Здесь, в stackoverflow, есть много других вопросов по таким темам, как mysql_real_escape_string mysql_real_escape_string и Регулярные выражения это может быть очень эффективным средством подтверждения содержания введенных пользователем данных.

Наилучшей практикой, ИМХО, является использование следующего подхода:1.создайте обработчик ошибок/исключений 2.запустите его при запуске приложения 3.обрабатывайте все свои ошибки изнутри

<?php

класс Debug { отладка класса

    public static setAsErrorHandler() {
         set_error_handler(array(__CLASS__, '__error_handler'));
    }

public static function __error_handler($errcode, $errmsg, $errfile, $errline) {
       if (IN DEV) {
                print on screen
           }
           else if (IN PRO) {
                log and mail
           } 
    }

}

Отладка::setAsErrorHandler();

?>

Вместо того чтобы выводить mysql_error, вы могли бы сохранить его в журнале.таким образом, вы можете отследить ошибку (и вы не зависите от того, сообщат ли о ней пользователи), а также зайти и устранить проблему.

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

помимо немедленной обработки ошибок в вашем коде, вы также можете использовать

http://us.php.net/manual/en/function.set-exception-handler.php
и
http://us.php.net/manual/en/function.set-error-handler.php

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

бывший:когда a mysql_connet возврат вызова FALSE Я бросаю new DBConnectionException(mysql_error()) и обращаться с этим "особым" способом:зарегистрируйте ошибку, информацию о подключении к БД (хост, имя пользователя, пароль) и т.д. И, возможно, даже отправьте электронное письмо команде разработчиков, уведомив их о том, что с БД действительно может быть что-то не так

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

Подавление ошибок с помощью @ происходит очень медленно.

Вы также можете использовать Google Forms для перехвата и анализа исключений без необходимости поддерживать базу данных или общедоступный сервер.Есть учебное пособие здесь это объясняет весь процесс.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top