2008-09-25 5 views
28

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

ответ

29

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

Чтобы сделать это, я рекомендую следующий тип инфраструктуры:

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

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

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

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

2

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

Как правило, вы можете использовать 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 />'); 
+2

Не использует функцию mysql_error() риск для безопасности, хотя? – VirtuosiMedia 2008-09-25 16:39:49

+1

вывод mysql_error пользователю потенциально опасен. – 2008-09-25 16:47:54

+0

вы можете иметь флаг в своем веб-приложении, который определяет, находитесь ли вы в тестовой среде или в процессе производства; в производстве, не показывать ошибку, просто зарегистрируйте ее. В тесте, сделайте оба. – 2008-09-25 19:19:29

1

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

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

2

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

Обработка ошибок идет рука об руку с безопасными методами кодирования, так как существует множество «ошибок», которые не приводят к простому сбою вашего сценария. в то время как не строго говоря об обработке ошибок как таковой, у добавленных байтов есть хорошая серия из 4 статей по некоторым основам безопасного программирования PHP, которые вы можете найти HERE. Здесь есть много других вопросов о stackoverflow по таким темам, как mysql_real_escape_string и Regular Expressions, которые могут быть очень полезны при подтверждении содержимого введенных пользователем данных.

1

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

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

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

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

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

2

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

<?php 

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

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();

?>

22

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

Ошибка с @ очень медленно.

0

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

Смежные вопросы