2011-04-21 8 views
10

)로 PHP 오류 처리기를 제한 PHP에서 특정 네임 스페이스에 대해서만 오류 처리기를 설정할 수있는 방법이 있습니까? 작은 프레임 워크를 구축하고 있는데, 사용자 정의 오류 핸들러를 설정하고 예외를 던져서 네임 스페이스 내에있는 모든 오류/경고 /주의 메시지를 잡아낼 수 있기를 원합니다. 이 특정 네임 스페이스 외부에서 트리거되는 오류는 일반적인 방식으로 동작해야합니다.특정 네임 스페이스 (예 :

PHP로 할 수 있습니까?

감사합니다.

+2

나는 그렇게 생각하지 않는다 :'debug_backtrace()'의 리턴 데이터에 네임 스페이스에 대한 정보가 없다. (당신의 에러 핸들러에 반응하는 방법을 알려줄 수있다. 무슨 일이 일어나는지 보길 바랍니다. –

답변

2

사과 실제로 게시하기 전에이 작업을 시도하지 않는 :

PHP가 오류 처리기 메서드로 전달 (일반적으로 무시되는)가 가리키는 배열 $ errcontext입니다 다섯 번째 (선택 사항) 매개 변수 현재 PHP 기호 표. 내 생각에 Rudie가 제안한 Exception의 백 트레이스에서 네임 스페이스를 추출 할 수 있다면 $ errcontext와 비슷한 방식으로 네임 스페이스 정보를 추출 할 수도있다. 그게 사실이라면 오류 처리기는 현재 네임 스페이스가 오류 처리기가 설계된 것과 일치하지 않으면 false를 반환하여 자체 네임 스페이스를 검사하고 "fall through"할 수 있습니다.

또한 오류 처리기는 "원칙적으로"(적어도 $ errcontext에 대한 내 제안이 실제로 작동하는 경우) 각 네임 스페이스에 대해 별도의 오류 처리기를 설정할 수 있음을 의미하는 "스택"될 수 있습니다.

나는이 접근법이 조쉬와 루디가 제안한 해결책보다 더 "우아한"것이라고 주장하지는 않지만, 당신이하려는 일에 부합하는 것처럼 보인다. 오류 처리기에 대한 범위 지정 제약 조건이 있습니다.

행운을 빈다.

+0

감사합니다. 정말 도움이되었습니다. $ errcontext는 내가 원하는 바가 아니었지만 좋은 아이디어가있었습니다. set_error_handler가 이전에 정의 된 함수를 오버라이드하기 때문에 콜백 함수 이름이 정적 배열에 저장되어있는 객체 내에 오류 처리기를 정의합니다. 그런 다음 각 함수에 대해 call_user_func를 사용하고 반환 값을 확인합니다. 그 기능들 내에서 저는 Rudie와 Josh의 답변에서 결합 된 아이디어를 사용할 것입니다. 실제로 오류 처리기를 스태킹하기위한 기본 구현이 없다는 사실은 수치 스럽습니다. 추악하고 비싸 ... 작동합니다. – Mikk

+0

사실, set_error_handler() *는 이전에 선언 된 오류 처리기를 덮어 쓰지 않습니다. 새로운 오류 처리기를 "스택"으로 푸시합니다. PHP 인터프리터는 오류를 처리 할 때 먼저이를 호출합니다. 새 오류 처리기가 종료되면 스택의 나머지 오류 처리기가 호출되지 않으므로 (마치 사용자가 파기 한 것처럼) 오류 처리기에서 값을 반환하면 스택의 다음 오류 처리기가 호출됩니다. IMO를 사용하면 PHP가 "콜백 함수 스택"을 배열 자체에로드하는 것보다 효율적으로 처리 할 수있게되지만 더 효과적 일 수 있습니다. – Peter

0

PHP로 할 수 있습니까?

아주 쉽게 말할 수 있습니다. 실제로 코드를 작성하지 않고,이게 내가 할 줄 것입니다 :

  1. 이 try/catch 블록을
  2. 캐치 모든 예외 (\Exception)
  3. 이 (어딘가 $exception->getTrace()에서) 마지막이라는 클래스를 찾기
  4. 만들기
  5. 승 수행 (이 경우 "Class") 클래스 이름을 제거 some\name\space\Class
  6. 사용 dirname($namespace) :
  7. 그 클래스는 이름으로 네임 스페이스를해야합니다 hatever 당신은 결과를 좋아하거나 제외 다시 발생 : throw $exception;

편집을
심지어 폐쇄 네임 스페이스가 있습니다

namespace oele\boele; 

$fn = function() { 
    throw new \Exception; 
}; 

try { 
    $fn(); 
} 
catch (\Exception $ex) { 
    print_r($ex); 
} 

$ex->getTrace()[0]['function'] 편집
너무 나쁜 oele\boele\{closure}

됩니다 trace 배열에는 없습니다. 모든 요소에 대해 'namespace' 키가 있습니다.

+0

나는 op가 거대한 try/catch 블록의 모든 것을 래핑 할 필요가 없다는 이유로'set_error_handler()'에 대해 묻고 있다고 생각한다. – knittl

+0

프레임 워크라면 대부분의 'FrontController에서 큰 try/catch 블록으로 싸야한다. 어쨌든 ... IMO – Rudie

+0

예, 나는 set_error_handler() 함수에 대해 오히려 생각하고있었습니다. 자신의 사용자 정의 예외를 잡아 당기는 것은 문제가되지 않아야합니다. – Mikk

1

나는이 (당신이 생각 얻을 수있는 최소한)이 작동하지 않는 경우에 내가 미리 사과 그렇게하기 전에이 작업을 수행하기 위해 시도하지 않은,하지만 내가이 달성하려고 할 방법은 다음과 같습니다

이후를 귀하의 네임 스페이스는 전체적으로 더 큰 프레임 워크가 될 것이고, 프레임 워크의 모든 클래스는 기본 클래스를 확장 할 것입니다 (기본 ClassClass를 호출 할 수 있습니다). 그 클래스 안에서 나는 errorHandler()라는 메소드를 생성 할 것이다. 이 함수 안에서는 예외 처리를 위해 무엇을 하든지 (아마 예외를 던지더라도) 할 수 있습니다.

이제이 기능을 사용 했으므로이 함수를 호출하는 방법을 알아 내야합니다. 네임 스페이스의 모든 객체는 BaseClass를 확장하므로 모두이 errorHandler() 메서드에 액세스 할 수 있습니다. 이제 코드 내부에서 일반적인 try/catch 블록을 사용하여 예외를 캡처하고 표준 예외 모델을 사용하는 대신 $ this-> errorHander()를 호출 할 수 있습니다. (이제 생각해보십시오. 여기에있는 일부 매개 변수 - catch 문에서 예외가 발생할 수 있습니다. 이렇게하면 문제가 발생할 것으로 예상되는 코드 부분에 필요한 것을 얻을 수 있습니다.

우리가 알아야 할 다음 부분은 기대하지 않는 예외와이 오류 처리기를 통해 경로를 계획하는 방법을 처리하는 것입니다. 이 해결책은 어딘가에 try/catch 블록을 사용하기 때문에 조금 더 까다 롭습니다. 이것이 프레임 워크이기 때문에, 모든 것이 index.php 나 다른 부트 스트랩 파일 (젠드 프레임 워크 같은 것)을 통해 실행된다고 가정 할 것입니다. 이 경우 프레임 워크의 시작이 시작될 때마다 try/catch를 넣을 것입니다. catch 블록에 예외가 발생하면 errorHandler() 메서드를 통해 실행할지 여부를 결정할 수 있습니다. 나는이 부분을 어떻게 든 관리해야하는데, 약간 더러운 느낌이 들며 더 나은 해결책이 있어야한다.

이 정보가 도움이 되었기를 바랍니다. 누군가가 마지막 부분을 얻는 방법을 알고 있다면 그렇게 대단히 기분이 좋지 않을 것입니다. 사전에