2010-01-11 5 views
4

두 개의 상호 작용하는 클래스에 대한 오류 메시지 구성에 약간의 문제가 있습니다. 하나의 객체는 무언가가 잘못되거나 예기치 않게 발생하는 '오류 - 틱 (error-ish)'상태를 갖지만 상황은 여전히 ​​해 당할 수 있습니다. 나는 예외를 사용하고 싶지 않다. 왜냐하면 그것들은 단지 메시지를위한 단일 문자열을 가지고 있기 때문이다. 2. 오류 이후에 객체에 접근하고자하기 때문에 2.. 적어도, 나는 그 get() 메소드 중 일부를 사용하여 예외 이후에 유용한 에러 메시지를 생성하고자한다.php에서 기술적 및 사용자 지향 오류 메시지 구성

궁극적으로 저는 의사 소통하고자하는 두 가지 메시지를 가지고 있습니다. 하나는 자신에게 코더로서, 어떤 것이 잘못되었다는 것입니다. 이 문자열은 파일, 라인, 함수/메소드, 인수 및 결과의 기술적 세부 사항을 갖습니다. 분명히, 나는 이것을 사용자에게 보여주고 싶지 않다. 그래서 사용자에게 보여줄 오류 메시지의 또 다른 문자열이있다. ("그 이메일 주소는 발견되지 않았다.").

그래서 여러 메시지에 대한 키로 예외 또는 상태 코드의 오류 코드를 사용할 수있는 오류 메시지 배열을 작성하려고 생각합니다. (이 작업을 수행하더라도 메시지 배열을 어디에 저장합니까?) 또 다른 옵션은 오류 상태 개체를 만드는 것일 수 있습니다.

디자인 패턴과 비슷한 "오류 패턴"같은 것이 있습니까?

답변

6

예외가 실제로 가장 좋은 옵션이며, 사용자가 요청한 모든 것을 수행합니다. 예외는 확장 할 수있는 클래스이므로 여러 메시지도 가능합니다. 예외를 발생시키는 객체를 예외로 전달할 수 있습니다.

<?php 
class ExampleException extends Exception { 
    private $secondMessage; 
    private $objectThatCausedIt; 
    public function __construct($secondMessage, $objectThatCausedIt) { 
    parent::__construct(
     "Descriptive message for developer", 
     // error code for this type of error 
     1000); 
    $this->secondMessage = $secondMessage; 
    $this->objectThatCausedIt = $objectThatCausedIt; 
    } 
    public function getSecondMessage() { 
    return $this->secondMessage; 
    } 
    public function getObjectThatCausedIt() { 
    return $this->objectThatCausedIt; 
    } 
} 

class Example { 
    public function causeException() { 
    throw new ExampleException("Second Message", $this); 
    } 
} 

이제 클래스를 사용하고 예외를 throw 할 수있는 호출을 try-catch 블록으로 래핑합니다.

<?php 
$example = new Example(); 
try { 
    $example->causeException(); 
} 
catch (ExampleException $e) { 
    // kind of pointless here, just an illustration 
    // get object that caused it and do something with it. 
    dump_and_log_function($e->getObjectThatCausedIt()); 
    // or just use $example, which is still "alive" 
    // and references the same instance 
    dump_and_log_function($example); 
} 

Extending Exception은 스택 백 트레이스를 얻는 이점이 있습니다. 백 트레이스에는 예외가 발생한 파일, 라인 및 기능과 같은 정보가 들어 있습니다. 또한 오류 코드, 메시지 등에 액세스 할 수 있습니다. 자세한 내용은 예외 (http://php.net/manual/en/class.exception.php)의 PHP 설명서를 읽으십시오.

오류 메시지와 로깅에 관해서는 대개 싱글 톤 클래스를 사용합니다.

<?php 
class Log { 
    private $logFile; 
    private static $instance; 
    /* Log instances may only be constructed in Log::getInstance */ 
    private function __construct() { 
    $this->logFile = fopen("path/to/log/file", "a"); 
    } 
    public logMessage($message) { 
    fwrite($this->logFile, $message); 
    } 
    public static getInstance() { 
    if (!self::$instance) self::$instance = new self(); 
    return self::$instance; 
    } 
} 

지금 다시 예외 처리 던져-catch 블록에 가고, 당신이 그것을 변경할 수 있습니다 에 : 싱글 톤 클래스 (. 경우에 당신이 모르는) 다음은 매우 간단한 예입니다 자체의 단 하나의 인스턴스가

<?php 
$example = new Example(); 
try { 
    $example->causeException(); 
} 
catch (ExampleException $e) { 
    // log developer message and backtrace 
    Log::getInstance()->logMessage($e->getMessage()); 
    Log::getInstance()->logMessage($e->getTraceAsString()); 
    // or more compact by casting to string 
    Log::getInstance()->logMessage((string)$e); 
    // and now print error for users 
    echo "<p>An Error has occured: {$e->getSecondMessage()}</p>"; 
} 

오류 메시지가 바로 표시되는 대신 Log 클래스에 메시지 배열이있는 속성을 만들 수 있습니다. 그런 다음 나중에보기 스크립트에 한 번에 나열 할 수 있습니다. logMessage 메소드가 메시지를 세션에 저장하여 새로 고친 후에 표시되도록 할 수도 있습니다 (세션에서 메시지를 지우는 것을 잊지 않거나 계속 표시됩니다 ;-).

+1

첫 번째 대답은 무엇인가요? SO에 오신 것을 환영합니다! –

0

I don't want to use exceptions, 1. because they only have a single string for the message, and 2. because I want to access the object after the error. At the very least, I want to use some of its get() methods to construct a useful error message after the exception!

독자적인 예외 클래스를 만들 수 있으며 PHP의 예외 클래스를 확장하여 필요한 지원을 추가 할 수 있습니다. 그러나 개발자와 클라이언트의 두 가지 설정을 가질 수 있습니다. 클라이언트 오류는 표시로 이동하고 개발자 오류는 로그 파일이나 다른 것으로 이동하지 않습니다.

두 개의 사용자 정의 예외 유형으로 변환됩니다 (더 많은 사용자가있을 수 있지만 두 개의 고유 한 기본 클래스를 말합니다).

+0

그러나 예외를 사용하는 경우 예외가 throw 된 후 개체를 사용할 수 없게하지 않습니까? 나는 그 시점 이후에도 여전히 그것을 사용하고 싶을지도 모른다라고 생각하고있다. 그러나 아마 나는 그것에서 나 자신을 말할 수있다. – user151841

+0

아니요, 예외를 "캐치 (Catch)"할 수 있습니다. 무엇이든 로그하여 진행하거나 종료 할 것인지 결정하십시오. 당신은 모든 융통성이 있습니다. –

+0

나는 몇 가지 테스트를 해왔고 예외가 객체를 파괴하는 것으로 보인다 : getMessage(), "
\ n"; } echo $ objExceptor-> test(). "
\ n"; ?> 그리고이 결과를 얻었습니다 : 붙잡은 예외 : 나는 예외입니다!
치명적인 오류 : 20 행에있는 비 객체의 member 함수 test()를 호출하십시오. – user151841

관련 문제