programing

하나의 캐치 블록에서 여러 예외 유형 포착

yoursource 2023. 1. 25. 08:51
반응형

하나의 캐치 블록에서 여러 예외 유형 포착

다음 얻을 수 있는 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-294

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(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그런 다음 에서 어떤 예외가 발생했는지 확인합니다.

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;
    }
}

다만, 상기의 회답과 같이 복수의 캐치 블록을 사용하는 것이 좋을지도 모릅니다.

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 || $ex instanceof BError){
        //handle AError and BError
    } elseif($ex instanceof CError){
        //handle CError
    } else {
       throw $ex; // an unknown exception occurred, 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
  }
}

여러 예외 처리

매우 간단합니다. 각 예외 유형에 대해 다음과 같은 캐치 블록이 있을 수 있습니다.

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(예외 $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);
}

이 다소 이상하게 보이는 접근법은 아마도 캐치 블록 구현 간에 많은 중복이 있는 경우에만 가치가 있을 것입니다.

폴스루 외에 고토를 사용하여 넘어갈 수도 있습니다.세상이 불타는 걸 보고 싶다면 아주 유용해.

<?php

class A_Error extends Exception {}
class B_Error extends Exception {}
class C_Error extends Exception {}

try {
    throw new A_Error();
} 
catch (A_Error $e) { goto abc; }
catch (B_Error $e) { goto abc; }
catch (C_Error $e) {
abc:
    var_dump(get_class($e));
    echo "Gotta Catch 'Em All\n";
}

3v4l.org

8.0가 없는 는, 방법으로 예외를 검출할 수 PHP 8.0 에서).$e, 디폴트 「」는 「」로 치환할 필요가 있습니다.ExceptionThrowable.

try {
    /* something */
} catch (AError | BError) {
    handler1()
} catch (Throwable) {
    handler2()
}

음, 7.1 이전 버전의 php용으로 작성된 솔루션이 많습니다.

다음은 모든 예외를 포착하고 싶지 않고 공통 인터페이스를 만들 수 없는 사용자를 위한 간단한 예입니다.

<?php
$ex = NULL
try {
    /* ... */
} catch (FirstException $ex) {
    // just do nothing here
} catch (SecondException $ex) {
    // just do nothing here
}
if ($ex !== NULL) {
    // handle those exceptions here!
}
?>

여기에 기재되어 있지 않은 다른 옵션은code다음과 같은 작업을 수행할 수 있습니다.

try {

    if (1 === $foo) {

         throw new Exception(sprintf('Invalid foo: %s', serialize($foo)), 1);
    }

    if (2 === $bar) {
        throw new Exception(sprintf('Invalid bar: %s', serialize($foo)), 2);
    }
} catch (Exception $e) {

    switch ($e->getCode()) {

        case 1:
            // Special handling for case 1
            break;

        case 2:
            // Special handling for case 2
            break;

        default:

            // Special handling for all other cases
    }
}

좋은 방법은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 에러를 검출합니다.이것이 도움이 됩니다.

class ErrorHandler{
    public static function excep_handler($e)
    {
        print_r($e);
    }
}
set_exception_handler(array('ErrorHandler','excep_handler'));

언급URL : https://stackoverflow.com/questions/8439581/catching-multiple-exception-types-in-one-catch-block

반응형