Aktualizacja:
Od PHP 7.1 jest to dostępne.
Składnia jest następująca:
try
{
// Some code...
}
catch(AError | BError $e)
{
// Handle exceptions
}
catch(Exception $e)
{
// Handle the general case
}
Dokumenty: https://www.php.net/manual/en/language.exceptions.php#example-287
RFC: https://wiki.php.net/rfc/multiple-catch
Zatwierdź: https://github.com/php/php-src/commit/0aed2cc2a440e7be17552cc669d71fdd24d1204a
Dla PHP przed 7.1:
Pomimo tego, co mówią te inne odpowiedzi, możesz złapać AErrori BErrorw tym samym bloku (jest to nieco łatwiejsze, jeśli to Ty definiujesz wyjątki). Nawet biorąc pod uwagę, że istnieją wyjątki, przez które chcesz „upaść”, nadal powinieneś być w stanie zdefiniować hierarchię odpowiadającą twoim potrzebom.
abstract class MyExceptions extends Exception {}
abstract class LetterError extends MyExceptions {}
class AError extends LetterError {}
class BError extends LetterError {}
Następnie:
catch(LetterError $e){
//voodoo
}
Jak widać tu i tutaj , nawet SPLdomyślne wyjątki mają hierarchię, którą można wykorzystać. Dodatkowo, jak stwierdzono w podręczniku PHP :
Po zgłoszeniu wyjątku kod następujący po instrukcji nie zostanie wykonany, a PHP spróbuje znaleźć pierwszy pasujący blok catch.
Oznacza to, że Ty też możesz mieć
class CError extends LetterError {}
które musisz obsługiwać inaczej niż AErrorlub BError, więc instrukcja catch wyglądałaby następująco:
catch(CError $e){
//voodoo
}
catch(LetterError $e){
//voodoo
}
Jeśli miałeś przypadek, w którym istniało dwadzieścia lub więcej wyjątków, które legalnie należały do tej samej nadklasy, i musiałeś poradzić sobie z pięcioma (lub jakąkolwiek dużą grupą) z nich w jedną stronę, a reszta w drugiej, nadal możesz to zrobić.
interface Group1 {}
class AError extends LetterError implements Group1 {}
class BError extends LetterError implements Group1 {}
I wtedy:
catch (Group1 $e) {}
Używanie OOP w przypadku wyjątków jest bardzo skuteczne. Używanie rzeczy takich jak hack get_classlub instanceofsą hackami i należy ich unikać, jeśli to możliwe.
Innym rozwiązaniem, które chciałbym dodać, jest umieszczenie funkcji obsługi wyjątków we własnej metodzie.
Mógłbyś
function handleExceptionMethod1(Exception $e)
{
//voodoo
}
function handleExceptionMethod2(Exception $e)
{
//voodoo
}
Zakładając, że absolutnie nie ma możliwości kontrolowania hierarchii klas interfejsów lub interfejsów wyjątków (i prawie zawsze będzie sposób), możesz wykonać następujące czynności:
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);
}
W ten sposób nadal masz tylko jedną lokalizację kodu, którą musisz zmodyfikować, jeśli twój mechanizm obsługi wyjątków wymaga zmiany, i pracujesz w ogólnych konstrukcjach OOP.