Я хотел бы более чистый способ получить следующую функциональность, чтобы поймать AError
и BError
в одном блоке:
try
{
/* something */
}
catch( AError, BError $e )
{
handler1( $e )
}
catch( Exception $e )
{
handler2( $e )
}
Есть какой-либо способ сделать это? Или я должен ловить их отдельно?
AError
и Berror
имеют общий базовый класс, но они также делятся им с другими типами, к которым я хотел бы перейти handler2
, поэтому я не могу просто поймать базовый класс.
php
exception-handling
Доминик Гурто
источник
источник
Ответы:
Обновить:
Начиная с PHP 7.1 это доступно.
Синтаксис:
Документы: https://www.php.net/manual/en/language.exceptions.php#example-287.
RFC: https://wiki.php.net/rfc/multiple-catch
Фиксация: https://github.com/php/php-src/commit/0aed2cc2a440e7be17552cc669d71fdd24d1204a
Для PHP до 7.1:
Несмотря на то, что говорят эти другие ответы, вы можете поймать
AError
иBError
в одном и том же блоке (это несколько проще, если вы тот, кто определяет исключения). Даже с учетом того, что есть исключения, которые вы хотите «провалить», вы все равно сможете определить иерархию, соответствующую вашим потребностям.Затем:
Как вы можете видеть здесь и здесь , даже
SPL
исключения по умолчанию имеют иерархию, которую вы можете использовать. Кроме того, как указано в руководстве по PHP :Это означает, что вы также можете иметь
который вы должны обрабатывать иначе, чем
AError
илиBError
, поэтому ваш оператор catch будет выглядеть так:Если у вас был случай, когда было двадцать или более исключений, которые на законных основаниях принадлежали одному и тому же суперклассу, и вам нужно было обработать пять (или любую большую группу) из них одним способом, а остальные - другим, вы можете ВСЕ ЕЩЕ сделать это.
А потом:
Использование ООП, когда дело доходит до исключений, очень эффективно. Использование таких вещей, как
get_class
илиinstanceof
являются взломами, и следует избегать, если это возможно.Еще одно решение, которое я хотел бы добавить, - добавить функциональность обработки исключений в свой собственный метод.
Вы могли бы иметь
Предполагая, что нет абсолютно никакого способа, которым вы можете управлять иерархиями или интерфейсами классов исключений (и почти всегда будет путь), вы можете сделать следующее:
Таким образом, у вас все еще есть единственное местоположение кода, которое вы должны изменить, если ваш механизм обработки исключений должен измениться, и вы работаете в общих конструкциях ООП.
источник
AError
может быть реализовано в библиотеке / файле, который обновляется третьей стороной.В PHP> = 7.1 это возможно. Смотрите ответ ниже.
Если вы можете изменить исключения, используйте этот ответ .
Если вы не можете, вы можете попробовать поймать все с
Exception
и затем проверить, какое исключение было сгенерированоinstanceof
.Но , вероятно, было бы лучше использовать несколько блоков catch, как описано в вышеупомянутом ответе .
источник
finally
утверждению. ;)... } else { throw($e); }
если оно не соответствует двум. Извините за неправильный синтаксис, не видел php некоторое время.В PHP 7.1 появилась возможность ловить несколько типов.
Так что это:
и
функционально эквивалентны.
источник
Начиная с PHP 7.1,
Интересно, что вы также можете:
и в более ранних версиях PHP:
источник
В этой статье рассматривается вопрос electrictoolbox.com/php-catch-multiple-exception-types . Содержание поста скопировано прямо из статьи:
Пример исключений
Вот некоторые примеры исключений, которые были определены для целей этого примера:
Обработка нескольких исключений
Это очень просто - для каждого типа исключения может быть блок catch:
Если выдается исключение, которое не обрабатывается ни одним из других операторов catch, оно будет обрабатываться блоком catch (Exception $ e). Это не обязательно должно быть последним.
источник
catch (Throwable $e)
отлавливать все исключения. Смотрите также: php.net/manual/en/class.throwable.phpВ качестве дополнения к принятому ответу вы можете переключить тип исключения, в результате чего будет получен шаблон, похожий на оригинальный пример:
источник
Вот разумная альтернатива, если у вас нет контроля над определением исключений. Используйте имя переменной исключения, чтобы классифицировать исключения, когда они перехвачены. Затем проверьте наличие переменной исключения после блока try / catch.
Этот несколько странный подход, вероятно, имеет смысл только в том случае, если между реализациями catch-блоков много дублирования.
источник
Помимо провала, также можно перешагнуть, используя goto . Это очень полезно, если вы хотите увидеть, как мир горит.
3v4l.org
источник
Отличный способ заключается в использовании
set_exception_handler
.Предупреждение!!! с PHP 7 вы можете получить белый экран смерти за фатальные ошибки. Например, если вы вызываете метод для необъекта, вы обычно получаете его
Fatal error: Call to a member function your_method() on null
и ожидаете увидеть это, если включено сообщение об ошибке.Вышеуказанная ошибка НЕ будет обнаружена
catch(Exception $e)
. Вышеуказанная ошибка НЕ вызовет какой-либо пользовательский обработчик ошибок, установленныйset_error_handler
.Вы должны использовать
catch(Error $e){ }
для отлова ошибок в PHP7. , Это может помочь:источник
catch (Throwable $e) { ... }
и покончить с этим. Смотрите также: php.net/manual/en/class.throwable.phpДругой вариант, не указанный здесь, - использовать
code
атрибут исключения, так что вы можете сделать что-то вроде этого:источник
extends \Exception
?Хм, есть много решений, написанных для php версии ниже 7.1.
Вот еще один простой способ для тех, кто не хочет перехватывать все исключения и не может создавать общие интерфейсы:
источник