За последние 24 часа нас посетили 54944 программиста и 1620 роботов. Сейчас ищут 1099 программистов ...

Exception

Тема в разделе "Вопросы от блондинок", создана пользователем tommyangelo, 15 сен 2010.

  1. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    Объясните пожалуйста, зачем нужны Exception.
    Чем try...catch отличается от простой проверки - if...else?
     
  2. Ensiferum

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

    С нами с:
    11 июл 2010
    Сообщения:
    1.292
    Симпатии:
    0
    Адрес:
    из секты поклонников Нео
    сам пока не использовал, но исключения помогают четко реагировать на различные события.

    У Шлосснейгла в "Профессиональное программирование на PHP" исключениям глава посвящена - что, как и зачем
     
  3. Gromo

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

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

    исключения используются для тех ситуаций, когда ошибка труднопредсказуема и зависит от внешних факторов.
    можно в пример привести открытие файла для записи. Какие ошибки могут возникнуть?
    1. файл не существует
    2. нету доступа для чтения
    3. нету доступа для записи
    4. файл заблокирован
    5. на диске не хватает места для записи (вот это особенно труднопредсказуемо)
    6. файл не может быть сохранён
    и т.д...

    этот не весь список и, возможно, некоторых ошибок не бывает, но для примера подойдёт.
    т.е. не всегда бывает возможность контроллировать всё if-ами.
     
  4. Ensiferum

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

    С нами с:
    11 июл 2010
    Сообщения:
    1.292
    Симпатии:
    0
    Адрес:
    из секты поклонников Нео
    в тему с бора:
     
  5. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    Ensiferum
    Шлосснейгл - то ли перевод плохой, то ли он сам так пишет...не догоняю немножко)))

    Gromo
    Так а почему я не могу проверить отработала fwrite или нет? Она же возвращает false при ошибке.

    Пока для себя вижу единственный плюс - возможность менять текст вывода сообщения об ошибке только в одном месте, а не по всей программе.
     
  6. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    PHP:
    1. <?php
    2. try{
    3.     $db=DB::newDB();
    4.     $db->select($sql);
    5.     while($row=$db->fetchAssoc()){
    6.         myGreatFunction($row);
    7.     }
    8.     return "Все пучком";
    9.  
    10. }catch(Exception $e){
    11.     return "Возникли проблемы.".PHP_EOL.$e->getMessage().PHP_EOL."Запрос не выполнен";
    12. }
    13.  
    14. ?>
    Вместо 3 if я использую 1 try...catch.

    Еще для поддержки транзакций.

    PHP:
    1. <?php
    2.     $db=DB::newDB();
    3. try{
    4.     $db->startTransaction();
    5.     $db->insert($sql);
    6.     myFunction();
    7.     $db->update($sql2);
    8.     $db->delete($sql3);
    9.     myOtherFunction();
    10.     $db->commit();
    11. }catch(Exception $e){
    12.     $db->rollback();
    13. }
    14.  
     
  7. MiksIr

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

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Ну в общем удобно тем, что обработчик ошибок может находится совсем в другом отдельном месте.
    В случае, если ошибки выдаются флагом или возвратом функции, анализ результата нужно как правило делать сразу после вызова функции, и только изредка можно этот флаг передать "наверх". Таким образом число таких проверок растет.

    Банальный пример - есть контроллер, которй делает несколько вызовов в БД.. не важно, через модель или чисто процедурный подход. Вот как отработать ошибку базы данных, что бы выдать красивую страничку "ой, сломалось"? Прерывать все внутри класса/процедуры работы с БД делая echo и exit? - не, это решение лишь для самых продвинутых говнокодеров. Отрабатывать false?... а вызовов таких в контроллере штук 10, и после каждого if ($ret === false) { error(); } - в общем тоже не особо красиво. А теперь вариант, что БД кидает исключение и где-то там, высоко, еще до контроллера даже (вызов контроллера заключен в try catch) это исключение ловится и создается сообщение ошибки. Красиво? Вполне.

    Вот, это был один из "житейских" вариантов.
     
  8. Gromo

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

    С нами с:
    24 май 2010
    Сообщения:
    2.786
    Симпатии:
    2
    Адрес:
    Ташкент
    tommyangelo
    сейчас программирую на питоне, который просто помешан на try-except - все ошибки ловятся таким образом.
    лично мне не нравится, но производство требует :)
    вот это и нравится мне в пхп.
     
  9. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    2 all

    Ну вот например, представим такую функцию
    if (!mysql_connect('четотам')) -- обрабатываем ошибку
    if (!mysql_select_db('четотам')) -- обрабатываем ошибку
    if (!mysql_set_names('четотам')) -- обрабатываем ошибку
    и т.д. Вот тут можно как-то использовать исключения? Каждую строку оформлять в try...catch

    Сейчас использую самописную(самонедописанную =) ) обработку.
    Типа такого if (!@mysql_connect('четотам')) ErrTrigger::Send('Ошибка подключения к базе', ERROR_ CRITICAL);
    Где константами задаются уровни ошибок.
    А внутри него уже определяется по уровню ошибки - останавливать приложение или нет.

    В чем недостатки и лучше ли здесь будут Exception?
     
  10. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    эксепшоны нужны чтобы ловить в одном месте одинаковые проблемы. типа отвалился коннект. не важно где он отвалился. уже шляпа и надо закрываться-сохраняться.
     
  11. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    tommyangelo
    PHP:
    1. <?php
    2.         public function __construct($config){
    3.             $this->setConfig($config);
    4.  
    5.             $this->link=mysqli_connect($this->host, $this->login, $this->pass);
    6.             if (!$this->link){
    7.                 throw new SqlException("Ошибка при подключении к серверу","Ошибка подключения","Connect");
    8.             }
    9.             $temp=mysqli_select_db($this->link,$this->db);
    10.             if (!$temp){
    11.                 throw new SqlException("Ошибка при выборе БД","Ошибка подключения","Connect");
    12.             }
    13.             $this->exec("set names utf8", false);          
    14.         }
    15.  
    igordata
    Не обязательно одинаковы.
    У меня не обработался запрос пользователя. Коннект отвалился или там данные неверные пришли. Ошибку в логи пользователю страницу "Упс...".
     
  12. phpdude

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

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    PHP:
    1.  
    2. try
    3. {
    4.     if(!$_POST['title']) throw new Exception("Please fill title");
    5.     if(!$_POST['title1']) throw new Exception("Please fill title1");
    6.     if(!$_POST['title2']) throw new Exception("Please fill title2");
    7.     if(!$_POST['title3']) throw new Exception("Please fill title3");
    8.     if(!$_POST['title4']) throw new Exception("Please fill title4");
    9.     if(!$_POST['title5']) throw new Exception("Please fill title5");
    10.  
    11.     $db->insert("tablename", postToArray($_POST));
    12. }
    13. catch(Exception $e)
    14. {
    15.     Response::addMessage($e->getMessage());
    16. }
    17.  
    :)

    красивее ифов, согласитесь и код проще :)
     
  13. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    эксепшоны это такой завуалированный полуавтоматичский аналог ностальгии по GOTO :D
     
  14. phpdude

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

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    igordata
    в чем то да походу)
     
  15. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    phpdude

    В твоем примере $db->insert отработает или нет?
     
  16. Костян

    Костян Активный пользователь

    С нами с:
    12 ноя 2009
    Сообщения:
    1.724
    Симпатии:
    1
    Адрес:
    адуктО
    $db=DB::create() ?
     
  17. iliavlad

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

    С нами с:
    24 янв 2009
    Сообщения:
    1.689
    Симпатии:
    4
    а как приложение останавливается? как следующая строчка узнаёт, что ей не надо выполняться?
     
  18. phpdude

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

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    ну если форма заполнена нормльно, то да, почему нет то?))
     
  19. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    Костян
    А разница?
     
  20. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    да, кстати. в чем разница (на доступном языке) между :: и ->
     
  21. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    phpdude
    Я мысль не закончил=)) Если хоть одно исключение будет - отработает или нет?

    По константе. В зависимости от уровня ошибки то ли в die(), то ли показываем сообщение и return
     
  22. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    tommyangelo
    нет конечно
    эксепшн сразу улетает в отлов как только происходит
     
  23. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    igordata
    Cпс, буду пробовать применять...
     
  24. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    tommyangelo
    ну не так много мест где имеет смысл. Но где имеет - то уж точно хорошо

    я вот недавно с яндексовским апи имел дело, и на коленке быстро-быстро набросал через if, но все равно эксепшна не хватает для спокойствия и красоты кода. =)
     
  25. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    Грубо говоря "::" вызывает метод класса, а "->" вызывает метод объекта.

    Почитай про статические свойства и методы класса.