Как стать автором
Обновить

Комментарии 65

Про исключения есть простое правило: нормальное поведение программы при нормальном поведении пользователя - 0 брошенных, 0 пойманных исключений. То есть если вы бросаете и отлавливаете исключения при том, что пользователь ничего криминального не сделал - вы переборщили с отказом от кодов возврата...

С другой стороны преимущество исключений в том, что их невозможно проигнорировать - так что если ваша программа не должна нормально продолжать работу после какого-то действия - время бросать исключение... __attribute__ ((warn_unused_result)) в PHP нету...
Ну это как-то слишком строго, надо просто помнить, что они небесплатны (хотя к динамическим языкам это в меньшей степени относится).
это неправильное пониание исключений как парадигмы. Брошеных может быть хоть миллиард - это нормально. Хоть одно не пойманное именно и означает фатальную ошибку.
Это вполне правильное понимание. Парадигма как раз подразумевает, что исключения не должны использоваться для того, что называется "normal workflow".
1. исключение - это "some condition that changes the normal flow of execution.". Следовательно, любая ошибка в процессе реализации задачи (ну скажем хотели файлик прочитать с винта, а прав нет) является исключением.
2. workflow != flow.
3. "Status returns are inferior to exceptions. All modern programming systems provide tools for exception handling. Use them." В PHP везде уйма варнингов и нотисов лишь по той простой причине, что слишком дофига std библиотеке переписывать надо.

Я причем не говорю что вообще нотисов и варнингов не должно быть. Должны быть, но те такие которые хочется ловить. Т.е. deprecation warning конечно никто швырять не будет.
в последнем абзаце - "которые НЕ хочется ловить". Ауч.
Вышеописанное подключение к базе может генерировать ошибку, когда сервер лежит. При этом и код верный и пользователь ничего плохого не делал.
В Python, например, кругом и рядом исключения. При открытии файла - исключение если нет.
Если ваш сервер отвечает "не шмогла я, не шмогла" - тут исключениям самое место, но если вы пытаетесь открыть 100 файлов хотя из них 99 не откруются и бросят exception - вы чего-то перемудрили со структурой программы.
Не понимание парадигмы, согласен с mocksoul.
Вот пример: пытаемся соединиться с сервером базы данных и в течении некоторого времени не получаем отклика (отваливаемся по таймауту) — кто тут виноват? Пользователь? Программа? — никто! Это нормальная работа приложения.
НЛО прилетело и опубликовало эту надпись здесь
давайте не будем говорить о Java как о родители ООП концепции :) потому как насколько знаю я, первым ООП языком была Simula ;)
НЛО прилетело и опубликовало эту надпись здесь
Обоснуйте, почему именно джавовский, а не сиплюсплюсный например?
НЛО прилетело и опубликовало эту надпись здесь
Вообще механизм исключений с ОО никак не связан. Исключения работают на уровне методов и представляют собой конструкции позволяющие управлять потоком выполнения. К объектам и классам прямого отношения не имеют.
НЛО прилетело и опубликовало эту надпись здесь
Это разумеется так, но лишь потому что в ОО любая сущность представляется в виде объекта. А возможность создания исключений разных типов — просто способ их классификации.

Возьмите любую классическую книжку по ОО (того же Гради Буча, например). Там нет ни слова про ислючения. Потому что они не имеют отношения к этой парадигме. Так же как и другие управляющие конструкции (if, for, switch и т.п.), а исключения как-раз из их числа.
НЛО прилетело и опубликовало эту надпись здесь
нет, никак не завязано. Исключения - это просто способ отматывать стеки обратно в поиске кода, который исключение поймает. В некоторых языках можно даже продолжить выполнение программы в том месте, где остановились, и это все при том что как правило исключения ловятся совсем в другом месте.

Вон, тот же питон позволяет выкидывать даже циферки и строки =).
Как интересно, а что такое "полностью ОО-язык"? Я вот могу на C++ написать программу, где не будет ни одного класса, и чего?
а на яве не сможете (:

полностью ОО-язык это как раз тот и есть который не позволяет процедурного программирования. Хотя необходимость наличия классов опять же этого не показывает.
Java это не чисто ОО язык программирования. Иначе что бы там делали примитивы? int, float, char, byte — все это не объекты в Java.

Наверное

По теме: заставить PHP выбрасывать исключения вместо вывода предупреждений можно, используя код из этой статьи: http://forum.vingrad.ru/faq/topic-164992…
к сожалению не все типы ошибок возможно будет отловить таким образом :(
Обе парадигмы нужны. Плохо получается когда разработчик увлекся и соблюдает "чистый" стиль.
от знания меры никто и не отказывался. я сам противник впадения в крайности, но если статья навела на мысль чт оя полностью отказываюсь от возвращаемых значений, то нет - это не так…
НЛО прилетело и опубликовало эту надпись здесь
да, неплохая статья, полезная)
Сам недавно переписал некоторые свои библиотеки на работу с исключениями. Вместо того чтобы возвращать false кидается исключение определенного типа. Например, есть функция добавления в БД какой-то записи, есть несколько причин, почему она может не смочь добавиться (дублирование уникального ключа, слишком линные данные, ошибка SQL). Раньше в таких случаях приходилось говорить, мол произошла ошибка, теперь есть возможность сказать какая именно (и прореагировать соотвествующе).

Что касается библиотек доступа к MySQL в PHP, то есть такая замечательная штука как PDO, который может выбрасывать исключения при ошибках SQL (с mysqli никогда не работал, поэтому не знаю, возможно, она тоже это умеет).

Инициализируется примерно так:

$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);


Далее, при желании, можно переопределить глобальную функцию обработки исключений:

set_exception_handler('exceptionHandler');


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

И еще. Поддержку исключений гораздо проще встроить в тело какой-то функции, чем поддержку выхода по ошибке, особенно, если функция уже возвращает какой-то результат, а нам вдруг понадобилось сделать выход из функции по ошибке, реакцию на ошибку, причем типов ошибок может быть несколько. Единственное, более менее простое решение без исключений, которое прямо сейчас приходит в голову - это возврат $errorCode в параметрах функции. А если у нас параметров много, причем есть со значениями по умолчанию (придется переписывать вызовы функции)? А если их переменное количество?
имейте ввиду, исключения в php - не родное. Когда я последний раз плотно занимался пхп (сомневаюсь что многое изменилось) было ещё огромная куча варнингов, нотисов и фатальных ошибок, которые на самом деле являются теми же исключениями но без возожности "поимки" выйдя из стека.
Спасибо, очень хорошая статья, у самого никак руки не доходили потестить скорость ексепшенов.
Исключения стоит использовать только если дальнейшие _корректное_ выполнение скрипта, при возникновение в блоке исключений ошибки, невозможно или приведет к непредсказуемым ошибкам. В остальных случаях достаточно простой проверки по if.
Жалко что исключения в РНР не перехватывают некоторые критические ошибки, на uncatched exception тратятся дополнительные ресурсы, да и пользователю может пролезть сообщение об ошибке... :(
Как страшно жить, зная что вокруг ходят разработчики софта, не знающие когда применять try catch (:
осталось только ещё понять что вы в своих примерах вообще используете исключения как простой status return.

Мощь-то их вся проявляется совсем не в таком коде.. а когда у тебя в десятой по глубине функции экспшн кидается, а ловишь ты его соооооовсем в другом месте. Тем самым код обработки ошибок вообще никак может быть не связан с бизнес логикой. Но оттого код ловли ошибок может стать "нивидимым".

Думать надо головой, в любой случае =).
Вообще не понятно зачем сравнивать операторы исключений и операторы условного перехода. Их в принципе сравнивать нельзя.
Если используется объектная модель с высоким уровнем абстракции, то само собой для отлавливания ошибок (точнее будет сказать событий, т.к. исключение - это не всегда ошибка) будут использоваться exceptions. Если используется структурное программирование - разумеется никакой речи о перехвате исключений и быть не может.
Наглядное (и очевидное) тому подтверждение - введение исключений начиная с PHP 5-й версии, т.к. от нее и начинается путь ООП в пхп-кодинге.
ООП не требует и даже не подразумевает использование исключений. это разные подходы к разным проблемам, которые можно, но вовсе не обязательно использовать вместе.
«ООП не требует и даже не подразумевает использование исключений.»

Можно поподробней?
конечно можно. но что ж непонятного? сам принцип объектно-ориентированного программирования нисколько не завязан и не требует использования исключений.
все результаты точно так же можно передавать в возвращаемом значении. единственное место, где этого сделать нельзя, это конструктор. но в конструкторах и так не рекомендуется производить сложную инициализацию, так что с этим проблем особых нет.
у нас в гайдлайнах для C++ сказано макимально просто и понятно: никаких исключений. без исключений. для Питона они разрешены, но тоже по желанию, и я, например, совершенно спокойно обхожусь без них.
Exceptions ввели, чтобы можно было отслеживать события от классов (объектов), а переменные испокон веков проверяют конструкцией if..else.
как показано в этом посте, довольно непрактично использовать механизм исключений для отслеживания каких-либо событий. обработка исключений - дорогое удовольствие. как выясняется, в php - просто неприлично дорогое, но и в других языках тоже. поэтому, как правильно сказал khim, нормальная ситуация - 0 исключений, 0 обработанных.
поэтому исключения - это просто другой способ обработки ошибок. если вы с помощью исключений пытаетесь "передать наверх" что-то иное, в обход стандартных путей, то вы что-то делаете неправильно.
В PHP неприлично дорогое???
Это как раз в компилируемых языках для него нужно создавать множество лишнего тормозящего кода.
В подобных же PHP языках, где стек вызовов и т.п. определяется на этапе выполнения, всё намного лучше.

% ./ee-test.sh
+ php --version
PHP 5.2.5 (cli) (built: Feb 29 2008 22:50:23)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
+ time php ee.php
0
6.64 real 5.82 user 0.80 sys
+ g++ --version
g++ (GCC) 3.4.6 [FreeBSD] 20060305
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

+ g++ -Wall -o ee ee.cc
+ time ./ee
0
3.84 real 3.74 user 0.00 sys
+ python --version
Python 2.5.2
+ time python ee.py
0
2.85 real 2.77 user 0.06 sys


с исходниками можно ознакомиться здесь
Понятно, что Ц будет быстрее ПХП по всякому.
Другое дело, что разница использования исключений в Си по сравнению с if в том же Си, будет гораздо больше, чем та же разница в ПХП. С учетом того, что и область применения Си гораздо чаще требует оптимизации, то тут гораздо серьезнее стоит вопрос о выборе между удобством и эффективностью.
> Другое дело, что разница использования исключений в Си по сравнению с if в том же Си, будет гораздо больше, чем та же разница в ПХП

вы топик внимательно читали?
Какой топик? Я реагирую на ваше сообщение "обработка исключений - дорогое удовольствие. как выясняется, в php - просто неприлично дорогое" и тесты скорости, которые говорят о том, что под дороговизной вы понимаете время выполнения. Покажите мне тест, который бы указывал на то, что исключения в ПХП неприлично медленно работают по сравнению с другими PHP-конструкциями.
цитирую топик:

True: 0.72382092475891
False: 0.85190796852112
No exception: 0.72565317153931
Exception: 14.176206827164

всё внимание на результат "Exception". если разница в 16 раз вас не смущает, то вперёд, передавайте сообщения с помощью исключений. не забудьте закупить дополнительно 15 серверов.
Не нервничайте, пожалуйста, и не язвите.
Можно и аргументы в функции передавать путем запись в файл и чтения его в самой функции. Можно и исключения непойми для чего использовать.
Если же использовать их для того, чего нужно то никакой "неприличной дороговизны" нет.
Число "16" само по себе не говорит абсолютно ничего.
давайте ещё раз повторим, о чём мы спорим.
я сказал - обработка исключений в пхп - неприлично дорогое удовольствие и продемонстрировал это на примерах - в сравнении с другими языками, а также с if-then-else в самом php.
я не говорю, что исключения использовать нельзя, но нужно иметь в виду, что это очень и очень дорого удовольствие, вот и всё. и да, в пхп - ещё более дорогое, чем в c++ и python.
Да, давайте определимся. Дорого использовать исключения там, где не надо или вообще дорого?
Я продолжаю настаивать на том, что при правильном использовании совсем не дорого.
Относительное число 16 в абсолютных величинах ничтожно (это из темы использовать двойный кавычки или нет), а в более сложных вариантах при большом количестве уровней, туева куча ифов скорее всего будет еще и тормознее.
правильное использование исключений - отсутствие исключений, то есть, как я уже сказал в самом начале, 0 исключений, в том числе обработанных.
я не говорю что их использовать совсем нельзя, но когда они происходят, то их обработка обходится дорого, и даже очень.

> число 16 в абсолютных величинах ничтожно

16 - это не абсолютная величина, а множитель. чтобы абсолютная величина оставалась ничтожной, умножаемое должно быть = 0 или около того. нормальная работа не должна порождать исключений.
вот тогда будет дёшево. с чем я, собственно, и не спорил - я с самого начала говорил, что именно *обработка* исключений обходится дорого.
if по сравнению с хотя бы запросом к базе, это 0 или около того.
Хорошо, видимо, вы не слишком чётко высказали свою мысль, а я не слишком чётко её понял :)
по-моему это и так понятно, что при использовании исключений - необходимо больше ресурсов, чем при использовании if...else. А вы думали будет по другому? А использование ООП по сравнению с обычным структурным программированием также требует намного больше ресурсов. А использование своего cgi-приложения оптимизированного под определенные нужды будет еще быстрее работать, чем php. И кодирование на ассемблере еще быстрее, чем любой другой язык...
Чем выше уровень языка, тем больше ресурсов требуется для реализации кода.
причем здесь дорогое или не дорогое??? Если используете ООП, то единственным методом обработки ОБЪЕКТНЫХ событий (событий которые происходят в классах) является исключения.
поэтому исключения - это просто другой способ обработки ошибок

И ошибок тоже! Я к примеру могу генерировать исключения для отладки кода.
исключения должны быть исключительными событиями. если вы напишете какой-нибудь обработчик запросов, который будет "кидать" их наверх с помощью исключений, вам потребуется в 16 раз больше серверов. вот такая простая арифметика.

факт состоит в том, что без них всегда можно обойтись и ООП не завязано на генерирование "объектных событий".
События - это и так исключительное явление :) Положительный результат - это тоже исключительное событие. Так что тут вопрос философский. :)
факт состоит в том, что без них всегда можно обойтись и ООП не завязано на генерирование "объектных событий".

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

оффтоп (хотя, может и не оффтоп :) )
Кстати, оч рекомендую хорошую книгу к прочтению :
http://rsdn.ru/res/book/web/php_5_prof.x…
зря рекомендуете эту книгу

невнятная
все галопом по европам
mvc вообще с какого-то непонятного ракурса приведен - пришлось "погуглить"

итого через 2месяца продал ее. т.к. нет ничего в ней, чтобы возможно пришлось еще раз прочитать
а с ней и Design Patterns за одно лучше сразу читать - тогда все понятно будет, т.к. именно на шаблоны проектирования идет уклон. Разумеется перед прочтением такой книги надо знать что такое ООП в действительности :) и pattern'ы проектирования неразрывно с ним связаны. вообщем гуглите.
а книга действительно хорошая, но не для новичков разумеется.
в этой книге рассмотрены всего несколько паттернов проектирования.
для изучения паттернов проектирования лучше приобрести книгу Э.Гамма, Р.Хелм, Р.Джонсон, Д.Влисседес "Приемы объектно-ориентированного проектирования. Паттерны проектирования"
согласен что книга не для новичков.
я ее покупал, надеясь увидеть подробное описание/применение MVC.
Вообще-то подробно про MVC можно почитать в книгах по Си. А переписывать такие же книги для пхп думаю будет глупо ибо пхп - это Си-подобный язык.
при неудаче соединения с СУБД, вывели бы соответствующую ошибку и прикатили выполнение сеанса
-----------------------

Исправьте, пожалуйста, в статье слово "прикатили" на "прекратили".

Спасибо.
<offtopeg&imho>
Смотрю вот на примеры кода и вижу яву, один в один. Сдается мне, что пхп 6.0 будет называть jPHP6 и странички JSPhp
не к добру это, ой не к добру
потеря самобытности и натяганые отовсюды фичи, смотаные изолентой, хорош язык, нечего сказать...
</offtopeg&imho>
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории