Подтвердить что ты не робот

Обработка ошибок в PHP

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

4b9b3361

Ответ 1

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

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

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

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

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

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

Ответ 2

Грубо говоря, ошибки являются наследием в 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());
}

Ответ 3

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

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

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

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

 @mysql_query($query);

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

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

Ответ 4

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

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

Ответ 5

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

<?php

class 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
           } 
    }
}

Debug::setAsErrorHandler();

?>

Ответ 6

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

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

Ответ 7

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

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

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

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

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

Ответ 8

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

Ответ 9

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