Обновить:
Начиная с PHP 7.1 это доступно.
Синтаксис:
try
{
// Some code...
}
catch(AError | BError $e)
{
// Handle exceptions
}
catch(Exception $e)
{
// Handle the general case
}
Документы: 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
в одном и том же блоке (это несколько проще, если вы тот, кто определяет исключения). Даже с учетом того, что есть исключения, которые вы хотите «провалить», вы все равно сможете определить иерархию, соответствующую вашим потребностям.
abstract class MyExceptions extends Exception {}
abstract class LetterError extends MyExceptions {}
class AError extends LetterError {}
class BError extends LetterError {}
Затем:
catch(LetterError $e){
//voodoo
}
Как вы можете видеть здесь и здесь , даже SPL
исключения по умолчанию имеют иерархию, которую вы можете использовать. Кроме того, как указано в руководстве по PHP :
Когда генерируется исключение, код, следующий за оператором, не будет выполнен, и PHP попытается найти первый соответствующий блок catch.
Это означает, что вы также можете иметь
class CError extends LetterError {}
который вы должны обрабатывать иначе, чем AError
или BError
, поэтому ваш оператор catch будет выглядеть так:
catch(CError $e){
//voodoo
}
catch(LetterError $e){
//voodoo
}
Если у вас был случай, когда было двадцать или более исключений, которые на законных основаниях принадлежали одному и тому же суперклассу, и вам нужно было обработать пять (или любую большую группу) из них одним способом, а остальные - другим, вы можете ВСЕ ЕЩЕ сделать это.
interface Group1 {}
class AError extends LetterError implements Group1 {}
class BError extends LetterError implements Group1 {}
А потом:
catch (Group1 $e) {}
Использование ООП, когда дело доходит до исключений, очень эффективно. Использование таких вещей, как get_class
или instanceof
являются взломами, и следует избегать, если это возможно.
Еще одно решение, которое я хотел бы добавить, - добавить функциональность обработки исключений в свой собственный метод.
Вы могли бы иметь
function handleExceptionMethod1(Exception $e)
{
//voodoo
}
function handleExceptionMethod2(Exception $e)
{
//voodoo
}
Предполагая, что нет абсолютно никакого способа, которым вы можете управлять иерархиями или интерфейсами классов исключений (и почти всегда будет путь), вы можете сделать следующее:
try
{
stuff()
}
catch(ExceptionA $e)
{
$this->handleExceptionMethod1($e);
}
catch(ExceptionB $e)
{
$this->handleExceptionMethod1($e);
}
catch(ExceptionC $e)
{
$this->handleExceptionMethod1($e);
}
catch(Exception $e)
{
$this->handleExceptionMethod2($e);
}
Таким образом, у вас все еще есть единственное местоположение кода, которое вы должны изменить, если ваш механизм обработки исключений должен измениться, и вы работаете в общих конструкциях ООП.