어떻게 하면 PHP 타입 힌트에서 “캐치 가능한 치명적인 오류”를 잡을 수 있을까요?

클래스 중 하나에 PHP5의 타입 힌트를 실장하려고 합니다.

class ClassA {
public function method_a (ClassB $b)
{} }
class ClassB {} class ClassWrong{} 

올바른 사용법:

$a = new ClassA; $a->method_a(new ClassB); 

생성 오류:

$a = new ClassA; $a->method_a(new ClassWrong); 

잡을 수 있는 치명적인 오류: ClassA::method_a()에 전달된 인수 1은 ClassB의 인스턴스여야 하며 ClassWrong의 인스턴스가 지정되어야 합니다.

그 오류(‘catchable’이라고 쓰여있기 때문에)를 잡을 수 있을까요?그렇다면 어떻게?



질문에 대한 답변



업데이트: 이것은 php 7에서 더 이상 발견할 수 있는 치명적인 오류가 아닙니다.대신 ‘예외’가 발생합니다.예외예외이지만 오류에서 파생된 “예외”(스파이크 따옴표 내)입니다. 여전히 슬로우 가능하므로 일반 트라이캐치 블록으로 처리할 수 있습니다.https://wiki.php.net/rfc/throwable-interface 를 참조해 주세요.

예.

<?php class ClassA {
public function method_a (ClassB $b) { echo 'method_a: ', get_class($b), PHP_EOL; } } class ClassWrong{} class ClassB{} class ClassC extends ClassB {}
foreach( array('ClassA', 'ClassWrong', 'ClassB', 'ClassC') as $cn ) {
try{
$a = new ClassA;
$a->method_a(new $cn);
}
catch(Error $err) {
echo "catched: ", $err->getMessage(), PHP_EOL;
} } echo 'done.'; 

인쇄하다

catched: Argument 1 passed to ClassA::method_a() must be an instance of ClassB, instance of ClassA given, called in [...] catched: Argument 1 passed to ClassA::method_a() must be an instance of ClassB, instance of ClassWrong given, called in [...] method_a: ClassB method_a: ClassC done. 

php7 이전 버전에 대한 오래된 답변:
http://docs.php.net/errorfunc.constants은 다음과 같이 기술하고 있습니다.

E_RECOVERABLE_ERROR(정수)
캐치 가능한 치명적인 오류입니다.이는 아마도 위험한 오류가 발생했지만 엔진이 불안정한 상태로 유지되지는 않았음을 나타냅니다.사용자 정의 핸들(set_error_handler()도 참조)에 의해 에러가 검출되지 않는 경우, 애플리케이션은 E_ERROR 이었던 것처럼 중단됩니다.

참고 항목: http://derickrethans.nl/erecoverableerror.html

예.

function myErrorHandler($errno, $errstr, $errfile, $errline) {
if ( E_RECOVERABLE_ERROR===$errno ) {
echo "'catched' catchable fatal errorn";
return true;
}
return false; } set_error_handler('myErrorHandler');
class ClassA {
public function method_a (ClassB $b) {} }
class ClassWrong{}
$a = new ClassA; $a->method_a(new ClassWrong); echo 'done.'; 

인쇄하다

'catched' catchable fatal error done. 

편집: 단, 트라이캐치 블록으로 처리할 수 있는 예외로 만들 수 있습니다.

function myErrorHandler($errno, $errstr, $errfile, $errline) {
if ( E_RECOVERABLE_ERROR===$errno ) {
echo "'catched' catchable fatal errorn";
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
// return true;
}
return false; } set_error_handler('myErrorHandler');
class ClassA {
public function method_a (ClassB $b) {} }
class ClassWrong{}
try{
$a = new ClassA;
$a->method_a(new ClassWrong); } catch(Exception $ex) {
echo "catchedn"; } echo 'done.'; 

참조: http://docs.php.net/ErrorException