2013-03-19 3 views
13

"Behat"단계를 실행할 때 Behat error handler이 "비 객체의 속성을 얻으려고 시도 중"오류를 예외로 변환합니다.PHP는 "비 객체의 멤버 함수 호출"예외로

이것은 단계가 실패로 표시되게하고 다음 시나리오에서 테스트 실행을 계속할 수 있으므로 매우 유용합니다.

그러나 "객체가 아닌 객체의 함수 호출"오류는 치명적이며 테스트 실행을 즉시 중단합니다 (결과를 xml로 작성하는 것을 중지하는 것을 포함하여). 이것은 도움이되지 않습니다.

내 질문은 :

  1. 이 두 가지 오류의 차이점은 무엇입니까? 서로 다른 "오류 수준"입니까? 문서화 된 곳은 어디입니까? 필자는 PHP 사이트와 Google을 검색하여 표준 참조를 찾을 수 없으며 각 오류의 특정 인스턴스를 디버깅하는 것에 대해 많은 질문을합니다.

  2. 스크립트를 완전히 중단하는 대신 후자의 오류를 예외로 변환 할 수있는 방법이 있습니까? "null"과 "->"을 역 참조하는 것은 "메모리 할당 문제와 같이 복구 할 수 없습니다"라는 오류가 될 것입니다.

업데이트 :

그것은 다음과 같습니다 PHP와 단지 알려진 문제입니다. 참조 :

  • #51882 비 객체에 대한 멤버 함수 호출이 예외를 던져해야
  • #46601
  • #51848 비 객체 메소드 호출 오류 "가 아닌 개체에서 멤버 함수를 호출"에 대한 E_RECOVERABLE_ERROR해야 set_error_handler()
  • #63538 "정의되지 않은 함수 호출"을 잡을 수

일부 페이지 잡을 수 있어야 eople은 "설계 상"이라고 말하지만 객체가 PHP에 추가되기 전에 정의되는 오류 수준의 인공물이라고 생각합니다. 비 OO 언어에서 존재하지 않는 함수를 호출하는 것은 심각한 오류이며 "치명적"또는 "복구 불가능"으로 설명 될 수 있습니다 (함수가 정의 될 수있는 비 OO 언어에서 - 심지어, 지나치게 비관적 인 것처럼 보이더라도). 요즘은 $a에서 "$a->f()"을 사용할 수 있으므로 "f"이 존재하지 않을 수도 있으며 치명적인 오류가 아니어야합니다 (cf. Java의 경우 NullPointerException이 될 수 있음)).

나는 새로운 질문에 날 리드 가정 :

_ 3. 당신은 대량 파괴 이전 버전과의 호환성을하지 않고, 치명적이지 않은 오류 "가 아닌 개체의 멤버 함수를 호출"하기 위해 PHP를 패치 할 수있는 방법 , 그리고 그 패치가 PHP로 받아 들여질 가능성을 극대화하기 위해 취할 수있는 조치는 무엇입니까?

업데이트 2 다시 패치 PHP는 :

이 수정 프로그램을 만들기위한 몇 가지 제한된 지원 on the PHP internals mailing list 있습니다.이제이 문제를 해결하고 RFC를 작성하기위한 패치를 작성하면됩니다.

답변

4

동적 인 개체의 속성을 선언 할 수 있지만 동적 메서드를 선언 할 수 없다는 것이 문제입니다. PHP가 함수가 존재하는지 확인할 수 없기 때문에 비 객체에 대한 메소드를 호출하려고하면 치명적인 오류가 발생합니다.

오류 번호가있는 간단한 출력은 this codepad을 확인하십시오.

"설정되지 않은 속성 설정 및 액세스"부분을 자세히 살펴보십시오. PHP는 "빈 값에서 기본 객체 만들기"라는 메시지를 보게됩니다. 따라서 클래스가 존재하지 않으면 PHP가 클래스를 생성합니다. 타입 캐스팅을 사용할 때도 마찬가지입니다. 참조 : object typecasting

따라서 동적 객체가 생성 된 기본 객체에서 해당 객체를 검사하므로 객체가 아닌 객체에 액세스 할 수 있습니다. 그러나 메서드에 액세스하면 해당 기본 객체에는 여전히 해당 메서드가 없습니다.

속성이 레벨 8 오류 및 방법 1 수준 오류를 반환하는 이유는 무엇입니까 (error levels 참조). 그리고 레벨 1 치명적 오류가 반환되므로이 프로세스를 계속 진행할 수 없습니다.

+0

감사합니다. 차이점에 대한 생각을 설명합니다. 누락 된 속성이 레벨 8 인 경우 누락 된 메소드가 레벨 1인지, 또는 실험으로 만 결정될 수 있는지 여부를 알려주십시오. – Rich

0

나는 당신에게 좋은 소식이있다 : Error Exceptions이라는 PHP 라이브러리가 있으며, 모든 PHP 오류를 잡을 수있는 예외로 변환한다.

일하는 방식이 상당히 극적으로 바뀌지 만 분명히이 일을하고 싶지 않은 사람은 분명합니다.

lib는 핵심 PHP 개발자 중 한 명인 Anthony Ferrara가 작성 했으므로 자신이하고있는 일을 잘 알고있을 수 있지만 자신이 직접하고 싶어하는 경우에는 set_error_handler() function을 사용하여 PHP에 연결합니다 ; PHP의 오류를 잡아 내고 싶다면 어떻게해야할까요?

희망이 있습니다.

+1

아직 시도하지는 않았지만 lib는 순수한 PHP로되어 있고'set_error_handler'와'register_shutdown_function' 만 사용합니다. 그래서 이것은 Behat이 링크 된 코드에서 할 수있는 것 이상을 수행하지 않을 것이라고 확신합니다. 내 원래의 질문. 특히'null' 값으로 객체 메소드를 호출하는 것을 복구 할 수 없습니다. 나는 당신이 그것을 달성하기 위해 PHP C 런타임을 패치해야한다고 생각합니다 (제 3 부 "q"참조) – Rich

관련 문제