Объясните пожалуйста, зачем нужны Exception. Чем try...catch отличается от простой проверки - if...else?
сам пока не использовал, но исключения помогают четко реагировать на различные события. У Шлосснейгла в "Профессиональное программирование на PHP" исключениям глава посвящена - что, как и зачем
в пхп, в отличие от других языков программирования, большинство проверок можно осуществить без использования исключений и это очень удобно. исключения используются для тех ситуаций, когда ошибка труднопредсказуема и зависит от внешних факторов. можно в пример привести открытие файла для записи. Какие ошибки могут возникнуть? 1. файл не существует 2. нету доступа для чтения 3. нету доступа для записи 4. файл заблокирован 5. на диске не хватает места для записи (вот это особенно труднопредсказуемо) 6. файл не может быть сохранён и т.д... этот не весь список и, возможно, некоторых ошибок не бывает, но для примера подойдёт. т.е. не всегда бывает возможность контроллировать всё if-ами.
Ensiferum Шлосснейгл - то ли перевод плохой, то ли он сам так пишет...не догоняю немножко))) Gromo Так а почему я не могу проверить отработала fwrite или нет? Она же возвращает false при ошибке. Пока для себя вижу единственный плюс - возможность менять текст вывода сообщения об ошибке только в одном месте, а не по всей программе.
PHP: <?php try{ $db=DB::newDB(); $db->select($sql); while($row=$db->fetchAssoc()){ myGreatFunction($row); } return "Все пучком"; }catch(Exception $e){ return "Возникли проблемы.".PHP_EOL.$e->getMessage().PHP_EOL."Запрос не выполнен"; } ?> Вместо 3 if я использую 1 try...catch. Еще для поддержки транзакций. PHP: <?php $db=DB::newDB(); try{ $db->startTransaction(); $db->insert($sql); myFunction(); $db->update($sql2); $db->delete($sql3); myOtherFunction(); $db->commit(); }catch(Exception $e){ $db->rollback(); }
Ну в общем удобно тем, что обработчик ошибок может находится совсем в другом отдельном месте. В случае, если ошибки выдаются флагом или возвратом функции, анализ результата нужно как правило делать сразу после вызова функции, и только изредка можно этот флаг передать "наверх". Таким образом число таких проверок растет. Банальный пример - есть контроллер, которй делает несколько вызовов в БД.. не важно, через модель или чисто процедурный подход. Вот как отработать ошибку базы данных, что бы выдать красивую страничку "ой, сломалось"? Прерывать все внутри класса/процедуры работы с БД делая echo и exit? - не, это решение лишь для самых продвинутых говнокодеров. Отрабатывать false?... а вызовов таких в контроллере штук 10, и после каждого if ($ret === false) { error(); } - в общем тоже не особо красиво. А теперь вариант, что БД кидает исключение и где-то там, высоко, еще до контроллера даже (вызов контроллера заключен в try catch) это исключение ловится и создается сообщение ошибки. Красиво? Вполне. Вот, это был один из "житейских" вариантов.
tommyangelo сейчас программирую на питоне, который просто помешан на try-except - все ошибки ловятся таким образом. лично мне не нравится, но производство требует вот это и нравится мне в пхп.
2 all Ну вот например, представим такую функцию if (!mysql_connect('четотам')) -- обрабатываем ошибку if (!mysql_select_db('четотам')) -- обрабатываем ошибку if (!mysql_set_names('четотам')) -- обрабатываем ошибку и т.д. Вот тут можно как-то использовать исключения? Каждую строку оформлять в try...catch Сейчас использую самописную(самонедописанную =) ) обработку. Типа такого if (!@mysql_connect('четотам')) ErrTrigger::Send('Ошибка подключения к базе', ERROR_ CRITICAL); Где константами задаются уровни ошибок. А внутри него уже определяется по уровню ошибки - останавливать приложение или нет. В чем недостатки и лучше ли здесь будут Exception?
эксепшоны нужны чтобы ловить в одном месте одинаковые проблемы. типа отвалился коннект. не важно где он отвалился. уже шляпа и надо закрываться-сохраняться.
tommyangelo PHP: <?php public function __construct($config){ $this->setConfig($config); $this->link=mysqli_connect($this->host, $this->login, $this->pass); if (!$this->link){ throw new SqlException("Ошибка при подключении к серверу","Ошибка подключения","Connect"); } $temp=mysqli_select_db($this->link,$this->db); if (!$temp){ throw new SqlException("Ошибка при выборе БД","Ошибка подключения","Connect"); } $this->exec("set names utf8", false); } igordata Не обязательно одинаковы. У меня не обработался запрос пользователя. Коннект отвалился или там данные неверные пришли. Ошибку в логи пользователю страницу "Упс...".
PHP: try { if(!$_POST['title']) throw new Exception("Please fill title"); if(!$_POST['title1']) throw new Exception("Please fill title1"); if(!$_POST['title2']) throw new Exception("Please fill title2"); if(!$_POST['title3']) throw new Exception("Please fill title3"); if(!$_POST['title4']) throw new Exception("Please fill title4"); if(!$_POST['title5']) throw new Exception("Please fill title5"); $db->insert("tablename", postToArray($_POST)); } catch(Exception $e) { Response::addMessage($e->getMessage()); } красивее ифов, согласитесь и код проще
phpdude Я мысль не закончил=)) Если хоть одно исключение будет - отработает или нет? По константе. В зависимости от уровня ошибки то ли в die(), то ли показываем сообщение и return
tommyangelo ну не так много мест где имеет смысл. Но где имеет - то уж точно хорошо я вот недавно с яндексовским апи имел дело, и на коленке быстро-быстро набросал через if, но все равно эксепшна не хватает для спокойствия и красоты кода. =)
Грубо говоря "::" вызывает метод класса, а "->" вызывает метод объекта. Почитай про статические свойства и методы класса.