2017-01-12 10 views
6

저는 PHP 온라인 매뉴얼에서 오늘 예외를 읽었으며 finally 키워드의 목적이나 실제 필요성을 아직 이해하지 못했습니다. 나는 약간의 포스트를 여기에서 읽었다. 그래서 나의 질문은 약간 다르다.keywod 'finally'는 PHP에서 사용하기위한 것입니다

function hi(){ 
    return 'Hi'; 
} 


try { 
    throw new LogicException("Throw logic \n"); 
} catch (InvalidArgumentException $e) { 
    echo $e->getMessage(); 
} 

echo hi(); 

출력 :

나는 우리가 이런 식으로 마지막으로 사용할 수있는 이해

Fatal error: Uncaught LogicException: Throw Logic in C:\Users\...a.php:167 
Stack trace: 
#0 {main} 
    thrown in C:\Users\...a.php on line 167 

그래서,이 경우 함수 하이(); 좋은 이유가있다. 예외가 처리되지 않으면 이해합니다 PHP 인터프리터가 스크립트를 중단합니다. 좋은. 지금까지 읽은 것과는 거리가 멀지 만 마침내 hi() 함수를 실행할 수 있습니다. 예외가 처리되지 않더라도 (이유는 모르지만)

그래서이 점을 이해합니다.

try { 
    throw new LogicException("Throw logic \n"); 
} catch (InvalidArgumentException $e) { 
    echo $e->getMessage(); 
}finally{ 
    echo hi(); 
} 

출력 :

예외 오류뿐만 아니라 함수의 '안녕하세요'메시지, 심지어 내가이에 대한 사용법을 모르는한다에
Hi 
Fatal error: Uncaught LogicException: Throw Logic in C:\Users\...a.php:167 
Stack trace: 
#0 {main} 
    thrown in C:\Users\...a.php on line 167 

이. 그러나 이것이 우리가 LogicException을 잡아 (LogicException $e)으로 잡아도 예외가 발생하지 않았더라도 실행중인 함수를 볼 수 있으며 'hi'메시지가 표시됩니다.

try { 
    throw new LogicException("Throw logic \n"); 
} catch (LogicException $e) { 
    echo $e->getMessage(); 
}finally{ 
    echo hi(); 
} 

출력 우리가 더 catch되지 않은 예외가없는 경우에도 그래서, 우리는 여전히 기능 hi() 실행 참조

// Throw logic 
// Hi 

이 예에서와 같이. 왜이 용도로 사용합니까? 예외가 잡히지 않은 경우 finally 블록을 최후의 수단으로 사용하는 것이 좋을 것이라고 생각했지만, 그렇지 않은 경우에도 사용하지 않는 이유는 무엇입니까?

+0

PHP 버전을 사용하고 있습니까? 진정한'finally '기능은 PHP 5.5까지 추가되지 않았습니다. –

+0

@AlecGordon php 7.0.1 –

+0

오, 이상 하네. [이 분석] (https://adayinthelifeof.nl/2013/02/12/php5-5-trycatchfinally/)에 따르면 finally 블록은 캐치되지 않은 예외 앞에 인쇄해야합니다. –

답변

2

finally 블록은 예외가 발생했는지 여부에 관계없이 특정 코드를 실행하려는 경우에 사용됩니다.

내가보기에 일반적인 사용 중 하나는 데이터베이스 연결을 닫는 것입니다. 예외가 있거나 없을 때마다이 작업을 수행하기를 원하므로 데이터베이스 서버가 수락하지 못하게하는 연결이 끊이지 않도록해야합니다 새로운 연결. 때문에 다이 문 마지막 변화, 더 치명적인 오류가 발생되지 않습니다

try { 
    throw new LogicException("Throw logic \n"); -> LogicException thrown 
} catch (InvalidArgumentException $e) { -> LogicException not catched 
    echo $e->getMessage(); 
}finally{ 
    echo hi(); -> code executed 
    die(); 
} 

:이 경우 너무

try { 
    $database->execute($sql); 
} catch (Exception $exception) { 
    $logger->log($exception->getMessage()); 
    throw $exception; 
} finally { 
    $database->close(); 
} 
+1

지금은 이해하지만 사용 사례는 매우 드물게 보입니다. 귀하의 예를 들어, 당신은 여전히 ​​던질 수있는 문장 전에 데이터베이스를 닫을 수 있고, 그것은 같은 것을 달성했을 것입니다. –

+2

@mvrht : 물론'finally'를 사용하여'throw'statement _without_를 사용하기 전에 DB 연결을 닫을 수 있지만, 그 경우에 요점은 : 첫째, 아마도 _every_ 예외는 있지만 특정 유형을 catch하지 않을 수도 있습니다. 다른 예외에 대한 close() 호출에 도달하지 마십시오. 둘째, 모든 예외를 잡아도, close()를 호출하기 위해 어딘가에 (try 블록이나 catch 블록 다음에) 중복 된 코드 행이 필요하다. 그 호출을'finally' 블록에 넣으면, 한번만 써야하고 모든 경우에 예외가 발생합니다 (예외가 발생했는지 여부, 잡히지 않은 경우). – dwytrykus

0

마지막으로 예외가 있는지 여부에 관계없이 실행해야하는 코드가 있어야합니다.

마침내없이 :

try { 
    $handle = fopen("file.txt"); 
    //Do stuff 
    fclose($handle); 
    return something; 
} catch (Exception $e) { 
    // Log 
    if (isset($handle) && $handle !== false) { 
     fclose($handle); 
    }  
} 

마지막으로 :

try { 
    $handle = fopen("file.txt"); 
    return something; 
} catch (Exception $e) { 
    // Log 
} finally { 
    if (isset($handle) && $handle !== false) { 
     fclose($handle); 
    }  
} 

당신이 함수가 리턴 한 후 자원을 확보하는 데 필요한 경우 decluttering의 비트를 제공합니다.

이것은 다음과 같은 경우에 더욱 유용하게 : 당신이 방법 전에 바로 실행됩니다 단일 fclose 호출에 각 리턴하기 전에 모든 필요한 fclose 호출을 줄일 수 있습니다이 경우

try { 
    $handle = fopen("file.txt"); 
    if (case1) { return result1; } 
    if (case2) { return result2; } 
    if (case3) { return result3; } 
    if (case4) { return result4; } 

} finally { 
    if (isset($handle) && $handle !== false) { 
      fclose($handle); 
     }  
} 

다른 코드 뒤에 있지만 반환합니다.

1
try { 
    throw new LogicException("Throw logic \n"); -> LogicException thrown 
} catch (InvalidArgumentException $e) { -> LogicException not catched 
    echo $e->getMessage(); 
}finally{ 
    echo hi(); -> code executed. "Hi" printed out 
} 

LogicException is here -> Fatal error 

:

이 의사 코드를 고려

try { 
    throw new LogicException("Throw logic \n"); -> LogicException thrown 
} catch (InvalidArgumentException $e) { -> LogicException not catched 
    echo $e->getMessage(); 
} catch (LogicException $e) { -> LogicException catched 
    echo $e->getMessage(); 
}finally{ 
    echo hi(); -> code executed 
}