За последние 24 часа нас посетили 21935 программистов и 1098 роботов. Сейчас ищут 682 программиста ...

Теория: Исключения и ошибки

Тема в разделе "Решения, алгоритмы", создана пользователем Ti, 24 мар 2007.

?

ну, как?

  1. Афтар жжот, песчы исчо

    0 голосов
    0,0%
  2. Понял ничего

    0 голосов
    0,0%
  3. -1, а нафега?

    0 голосов
    0,0%
  4. НЕРАБОТАЕТ!!!

    0 голосов
    0,0%
  5. Неасилил, патамушта многа букаф

    0 голосов
    0,0%
  1. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    PHP:
    1. <?
    2. class UserErrorList extends Exception {
    3.     public $list;
    4.     function add($message, $code) {
    5.         $this->list[] = compact('message', 'code');
    6.     }
    7. }
    8.  
    9.  
    10. try {
    11.     $errorList = new UserErrorList;
    12.     $errorList->add('first', 1);
    13.     $errorList->add('last', 2);
    14.     throw $errorList;
    15. }
    16. catch (UserErrorList $e) {
    17.     echo '<pre>';
    18.     print_r($e->list);
    19. }
    HTML:
    1. Array
    2. (
    3.     [0] => Array
    4.         (
    5.             [message] => first
    6.             [code] => 1
    7.         )
    8.  
    9.     [1] => Array
    10.         (
    11.             [message] => last
    12.             [code] => 2
    13.         )
    14.  
    15. )
     
  2. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Ti
    Т.е. если у тебя какой-то из валидаторов формы поднимает исключение, тебе нужно его перехватывать и взамен поднимать другое самодельное исключение, которое способно хранить несколько сообщений? А если другой валидатор тоже сработает, как это разруливать? Не доходит до меня :)
     
  3. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    понял ничего, в кратце, к коде или псевдо коде можно?
     
  4. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Вот я о чем - простой пример использования исключений для валидации формы.
     
  5. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    Я не вижу проблемы о которой Вы говорите.
    Если у Вас исключения создают непонятки, мб Вы что-то делаете не так.
     
  6. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    предложенный тобой вариант ничем не лучше обычного ifelse
    PHP:
    1. $errors = array();
    2. $errors['first']= 1;
    3. $errors['last']= 2;
    4. if ($errors):
    5.     echo '<pre>';
    6.     print_r($errors);
    7. else:
    8.     echo 'гламурно';
    9. endif;
     
  7. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
     
  8. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Ti
    Пока что я еще ничего не делаю, лишь пытаюсь понять, насколько механизм исключений хорош для решения той или иной проблемы ;)
    До сегодняшнего дня я искренне считал, что исключения предназначены для обработки фатальных ошибок, возникающих в системе. Т.е. для обработки ситуаций, которые нельзя обработать другими методами. Поскольку некоторые товарищи пытаются здесь представить механизм исключений как некую панацею (и даже сравнивают скорости работы - ну вот объясните мне, какая разница, с какой скоростью будет обработала фатальная ошибка приложения?), я пытаюсь понять, как можно их еще использовать. Psih предложил неплохой пример: обработка формы валидаторами. Соответственно есть набор валидаторов, каждый из которых "пропускает" через себя значение и поднимает исключение, если оно неверно. Вопрос: как на выходе получить и отловить одно исключение, собравшее в себя все ошибки валидации? dark-demon прав, если форма вылетает после первой ошибки - это убожество.
     
  9. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    О фатальных ошибках вообще молчу - причины и результаты их ясны.
    Исключения это прежде всего проблемы предусмотренные разработчиком.
    Еще раз подчеркиваю, исключения порождает код, который не знает как их обработать. Это их громадное преимущество. Исключения позволяют добиться лучшей инкапсуляции.
    dark-demon собирает ошибки в массив, а при использовании исключений их можно собрать в одно исключение.
     
  10. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    ну и глупость ты написал :)
    "сделай то, не зная что" (с) сказка.
     
  11. Davil

    Davil Guest

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

    AlexGousev Активный пользователь

    С нами с:
    25 мар 2006
    Сообщения:
    1.505
    Симпатии:
    0
    Адрес:
    Москва
    Davil
    Просматриваешь «Непрочитанные сообщения» за последние полгода? ;)
     
  13. Davil

    Davil Guest

    AlexGousev

    хаха =)
    Да вот интернет подключил =))
    решил выбраться на свой любимый форум =)
    А на работе лазить - шеф матерится...
     
  14. korchasa

    korchasa Активный пользователь

    С нами с:
    4 май 2006
    Сообщения:
    12
    Симпатии:
    0
    Исключение != ошибка. Исключение это исключительная ситуация, которую возможно удастся обработать в вышестоящем функционале. Неотловленное исключение == ошибка.

    Если вместо исключений использовать реткоды, то это приводит к излишней связности снизу-вверх + return занят.
     
  15. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    update

    добавил:
    PHP:
    1. <?
    2. /*
    3. Любой класс «родитель» может отлавливать исключения «детей».
    4. Исключение Exception - родитель всех исключений, им можно отловить ЛЮБОЕ исключение.
    5. Имеет значение порядок блоков catch.
    6. */
    7.  
    8. echo '<h2>Наследование в исключениях</h2>';
    9.  try {
    10.      throw new a;
    11.  }
    12.  catch (Exception $e) {
    13.      echo '<h3>Отловили исключение класса ',get_class($e),' при помощи родителя Exception</h3>';
    14.  }
    15.  catch (a $e) {
    16.      echo '<h3>Этот блок не отработает, т.к. его нужно было разместить раньше</h3>';
    17.  }

    убрал информацию о set_exception_handler, грамотнее глобально отлавливать Exception
     
  16. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    update

    добавил:
    PHP:
    1. <?
    2. /*
    3. можно отлавливать исключения по интерфейсу
    4. */
    5. interface MyExceptionInterface {}
    6. class MyException extends Exception implements MyExceptionInterface {}
    7. try {
    8.     throw new MyException;
    9. }
    10. catch (MyExceptionInterface $e) {
    11.     echo "Поймали исключение с интефейсом MyExceptionInterface";
    12. }
     
  17. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    кусок кода:
    PHP:
    1. <?php
    2.         if(!empty($_POST['title'])) {
    3.             $sql = sprintf("SELECT id FROM pr_province WHERE title=%s", cleanQ(ucfirst(strtolower($_POST['title']))));
    4.             if($db->numrows($db->query($sql))) {
    5.             exit(header('Location: admin.php?do=add&add=province&amp;error='.1));
    6.             }
    7.             $sql = sprintf("INSERT INTO pr_province (title) VALUES (%s)", cleanQ(ucfirst(strtolower($_POST['title']))));
    8.             $db->query($sql);
    9.             exit(header('Location: admin.php?do=add&add=province'));
    10. ?>
    как сделать с исключениями проверку: не пустое ли поле title, нет ли такой записи в БД, выполнился ли запрос и тд?
     
  18. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Метод query должен бросать исключение в случае ошибки.

    PHP:
    1. try {
    2.     if (empty($_POST['title'])) {
    3.         throw new Exception('Field title is empty');
    4.     }
    5.  
    6.     //...
    7.     $db->query('...');
    8.     //...
    9. } catch (Exception $e) {
    10.     print 'Error ' . $e->getMessage();
    11. }
    Правда я не сторонник валидации форм через исключения.
     
  19. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    да уж, теперь пожалуй и я не сторонник валидации форм через исключения :lol:
     
  20. mazzaika

    mazzaika Активный пользователь

    С нами с:
    14 авг 2007
    Сообщения:
    2
    Симпатии:
    0
    М.б. взглянем на все это с другой стороны?
    Проверка условными операторами безусловно на много быстрее, но она выполняется при каждом прогоне, а исключения обрабатываются только в случае возникновения ошибки...

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

    Например ввод пользователем неправильного email-адреса вполне естественно и часто имеет место быть... Если честно, до прочтения этой темы я и не думал об использовании исключений при проверке данных, введенных пользователем...

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

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

    Жду ваших комментариев... :)
     
  21. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    mazzaika
    Исключения затормаживают само выполнение кода, так что в этом смысле проверка передачи неправильного значения обычным if будет очень сильно быстрее, возьмите проверьте тестом. Где это не очень важно - это при получении формы от пользователя - там удобнее проверить акуратно и выдать исключение при ошибке, красиво всё проставить обратно в форму, чем городить кучу if () { } else { $error = true; $msg = 'some error'; } - тут исключения хорошо помогают.
     
  22. dAllonE

    dAllonE Guest

    Ti, красиво.
    С иключениями начал разбираться совсем недавно и еще нигде не использовал (в PHP), твой пример мне очень помог.

    В закладки!

    А крайне редко это насколько?
    Хочу в своем велосипеде неавторизованным админам отправлять исключение, как думаешь, оправданно?
     
  23. mazzaika

    mazzaika Активный пользователь

    С нами с:
    14 авг 2007
    Сообщения:
    2
    Симпатии:
    0
    Каюсь... Не знал...


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

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

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Не корректно заполненная форма это не исключение, а рядовая ошибка. Исключение это когда SQL запрос не может быть выполнен из-за какой-то ошибки, или например когда данные не могут быть записаны в файл, т.к. не хватает прав. Для меня исключение это ошибка, которая, в принципе, не может произойти, если программа функционирует в нормальном режиме.