나는 캐치로, 다음과 같은 기능을 얻을 수있는 청소기 방법을 싶습니다 AError
와 BError
한 블록에 :
try
{
/* something */
}
catch( AError, BError $e )
{
handler1( $e )
}
catch( Exception $e )
{
handler2( $e )
}
이것을 할 수있는 방법이 있습니까? 아니면 따로 잡아야합니까?
AError
및 Berror
공유 기본 클래스를 가지고,하지만 난을 통해 가을에하고 싶은 것을 그들은 또한 다른 유형과 공유 handler2
난 그냥 기본 클래스를 잡을 수 있습니다.
답변
최신 정보:
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
7.1 이전의 PHP :
이러한 다른 답변의 말에도 불구하고, 당신은 잡을 수 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
}
동일한 수퍼 클래스에 합법적으로 속한 20 개 이상의 예외가 있고 그 중 5 개 (또는 큰 그룹)를 한 가지 방법으로 처리해야하고 나머지는 다른 방법으로 처리해야하는 경우에도 여전히이를 수행 할 수 있습니다.
interface Group1 {}
class AError extends LetterError implements Group1 {}
class BError extends LetterError implements Group1 {}
그리고:
catch (Group1 $e) {}
예외와 관련하여 OOP를 사용하는 것은 매우 강력합니다. 사용 일이 좋아 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);
}
이러한 방식으로 예외 처리 메커니즘을 변경해야하는 경우 수정해야하는 유일한 단일 코드 위치가 있으며 일반적인 OOP 구성 내에서 작업하고 있습니다.
답변
PHP> = 7.1에서는 이것이 가능합니다. 아래 답변을 참조하십시오 .
예외를 수정할 수 있으면 이 답변을 사용하십시오 .
당신이 할 수 없다면, 당신은 모두를 잡아서 시도 Exception
하고 어떤 예외가 발생했는지 확인할 수 instanceof
있습니다.
try
{
/* something */
}
catch( Exception $e )
{
if ($e instanceof AError OR $e instanceof BError) {
// It's either an A or B exception.
} else {
// Keep throwing it.
throw $e;
}
}
그러나 앞서 언급 한 답변에서 설명한대로 여러 catch 블록 을 사용하는 것이 좋습니다 .
try
{
/* something */
}
catch( AError $e )
{
handler1( $e );
}
catch ( BError $b )
{
handler2( $e );
}
답변
오는 PHP 7.1은 여러 유형을 잡을 수 있다는 것입니다.
그래서이 :
<?php
try {
/* ... */
} catch (FirstException $ex) {
$this->manageException($ex);
} catch (SecondException $ex) {
$this->manageException($ex);
}
?>
과
<?php
try {
} catch (FirstException | SecondException $ex) {
$this->manageException($ex);
}
?>
기능적으로 동일합니다.
답변
PHP 7.1부터
catch( AError | BError $e )
{
handler1( $e )
}
흥미롭게도 다음을 수행 할 수 있습니다.
catch( AError | BError $e )
{
handler1( $e )
} catch (CError $e){
handler2($e);
} catch(Exception $e){
handler3($e);
}
그리고 이전 버전의 PHP에서 :
catch(Exception $ex){
if($ex instanceof AError){
//handle a AError
} elseif($ex instanceof BError){
//handle a BError
} else {
throw $ex;//an unknown exception occured, throw it further
}
}
답변
이 기사는 electrictoolbox.com/php-catch-multiple-exception-types 질문을 다룹니다 . 기사에서 직접 복사 한 게시물의 내용 :
예외 예
다음은이 예제의 목적으로 정의 된 예외 예입니다.
class FooException extends Exception
{
public function __construct($message = null, $code = 0)
{
// do something
}
}
class BarException extends Exception
{
public function __construct($message = null, $code = 0)
{
// do something
}
}
class BazException extends Exception
{
public function __construct($message = null, $code = 0)
{
// do something
}
}
여러 예외 처리
매우 간단합니다. 각 예외 유형마다 catch 블록이있을 수 있습니다.
try
{
// some code that might trigger a Foo/Bar/Baz/Exception
}
catch(FooException $e)
{
// we caught a foo exception
}
catch(BarException $e)
{
// we caught a bar exception
}
catch(BazException $e)
{
// we caught a baz exception
}
catch(Exception $e)
{
// we caught a normal exception
// or an exception that wasn't handled by any of the above
}
다른 catch 문에 의해 처리되지 않는 예외가 발생하면 catch (Exception $ e) 블록에 의해 처리됩니다. 반드시 마지막 일 필요는 없습니다.
답변
허용 된 답변의 확장으로 Exception 유형을 전환하여 원래 예제와 다소 유사한 패턴을 만들 수 있습니다.
try {
// Try something
} catch (Exception $e) {
switch (get_class($e)) {
case 'AError':
case 'BError':
// Handle A or B
break;
case 'CError':
// Handle C
break;
case default:
// Rethrow the Exception
throw $e;
}
}
답변
예외 정의를 제어 할 수없는 경우 합리적인 대안이 있습니다. 예외가 발생했을 때 예외를 분류하려면 예외 변수의 이름을 사용하십시오. 그런 다음 try / catch 블록 다음에 예외 변수를 확인하십시오.
$ABError = null;
try {
// something
} catch (AError $ABError) { // let the exception fall through
} catch (BError $ABError) { // let the exception fall through
} catch (Exception $e) {
handler2($e);
}
if ($ABError) {
handler1($ABError);
}
캐치 블록 구현 사이에 중복이 많은 경우이 다소 이상하게 보이는 접근 방법은 그만한 가치가 있습니다.