2011-10-15 10 views
-1

私はプロジェクトオブジェクトを持っています。 ユーザーは、ワーカーオブジェクトを割り当てることができます。PHP例外とユーザメッセージ

プロジェクトオブジェクトには、すべての適切なフィールドが設定されています。 場合によっては、プロジェクトにフィールドがありません。

作業者がプロジェクトに割り当てるには、プロジェクトに必要なすべてのフィールドが設定されている必要があります。

は、これを解決するために、私はこのような例外をスロー:これに伴う問題は、私は表示する必要があるということです

 

if ($project->startDate == false) { 
    throw new Exception("Missing startDate attribute for project id: $id"); 
} 


if ($project->finishDate == false) { 
    throw new Exception("Missing finishDate attribute for project id: $id"); 
} 

if ($project->startDate > $project->finishDate) { 
    throw new Exception("Invalid start date for project id: $id"); 
} 

(ここでは、パターンを見つけようとしません、実際の例では、より複雑です)カスタムメッセージを毎回ユーザーに送信します。たとえば、最初のエラーがスローされた場合、「プロジェクトの開始日を設定してください。

どうすればいいですか?

答えて

5

だけtry .. catchで独自の例外クラスとあなたの全体のコードを定義します。

class FormException extends Exception { 
    private var $userMessage; 
    public function __construct($message, $userMessage) { 
    parent::__construct($message); 
    $this->userMessage = $userMessage; 
    } 
    public function getUserMessage() {return $this->userMessage;} 
} 

try { 
    // Whole code goes here, probably a function call 
    throw new FormException("Missing startDate attribute for project id: $id", 
          'Please setup the project start date'); 
} catch (FormException $e) { 
    echo $e->getUserMessage(); 
    error_log($e->getMessage()); 
} 

ところで、あなたは文字列で変数の内容を含めたい場合は、二重引用符("id: $id")を使用するか、または連結のいずれか( 'id: ' . $id)。おそらくgetErrorMessageと呼ばれる新しいメソッドを作成し、プロジェクトのクラス内

try 
{ 
    $Message = ''; 
    if ($project->startDate == false) { 
    $Message = "Please setup the project start date\n"; 
    throw new Exception("Missing startDate attribute for project id: $id"); 
    } 


    if ($project->finishDate == false) { 
    $Message = "Please setup the project finish date\n"; 
    throw new Exception("Missing finishDate attribute for project id: $id"); 
    } 

    if ($project->approved == false) { 
    $Message = "Please setup the project approved field\n"; 
    throw new Exception("Missing approved attribute for project id: $id"); 
    } 
} 
catch(Exception $Ex) 
{ 
    // Log in some way you like the $Ex-getMessage(); 
    echo nl2br($Message); 
} 
+0

私はすでにスローされ、例外です。問題は、それぞれのケースごとに異なるものを表示する必要があることです。また、私はerror_logにそれを記録するので、私はメッセージを変更することができません、私は技術的な情報が必要です。 – danidacar

+0

@danip申し訳ありませんが、このコードはあなたが記述したものとまったく同じです。これは、例外オブジェクトを作成した引数を表示します。エラーを記録する場合は、 '' echo''の代わりに['error_log'](http://php.net/manual/en/function.error-log.php)を呼び出してください。 – phihag

+0

私の問題はもう少し抽象的です。テクニカルエラーメッセージ(エラーログで使用できる)を投げる方法と、それぞれのケースに対してユーザーに異なるフレンドリーなメッセージを与える方法です。 – danidacar

1

はこれを試してみてください。

この関数はチェックを行う必要があります(プロジェクトの外部で検証を行う具体的な方法やプロジェクトの検証オブジェクトを作成する必要はありません)。次に:

if ($message = $project->getErrorMessage()) 
{ 
    throw new Exception(sprintf('%s (project id: %d)', $message, $id)); 
} 

デザイン上の理由から例外をスローしないことにした場合でも、これは使用されます。

単一のメソッドよりも詳細な情報を自然に提供できるバリデータオブジェクトを使用すると、柔軟性が増します。だからそれは良いことかもしれません:

class ProjectValidator 
{ 
    private $project; 
    private $errors; 
    public function __construct($project) 
    { 
     $this->project = $project; 
    } 
    public function isValid() 
    { 
     // run your checks, add errors to the array as appropriate. 

     $errors = array(); 

     if (!$this->project->startDate) 
     { 
      $errors[] = 'Missing startDate attribute'; 
     } 

     if (!$this->project->finishDate) 
     { 
      $errors[] = 'Missing finishDate attribute'; 
     } 

     if (!$this->project->approved) 
     { 
      $errors[] = 'Missing approved attribute'; 
     } 

     $this->errors = $errors; 

     return (bool) count($this->errors); 
    } 
    public function getErrors() 
    { 
     return $this->errors; 
    } 
} 

$validator = new ProjectValidator($project); 
if (!$validator->isValid()) 
{ 
    // throw an exception or do whatever you want in case it's not valid 

    $errors = $validator->getMessages(); 
    $message = sprintf("Project id: %d has the following %d error(s):\n", $id, count($errors));   
    foreach($errors as $index => $error) 
    { 
     $message .= sprintf("%d. %s\n", $index+1, $error); 
    } 

    throw new Exception($message); 
} 
+0

エラーメッセージは、ユーザーの技術的なものです。私は、それぞれのケースに対して異なるフレンドリーなユーザーメッセージを表示し、ログに例外メッセージを使用する必要があります。 – danidacar

+0

終了日はどうですか?エコーは開始日を言うでしょう – danidacar

+0

@ダニップあなたはそうです。最終更新はうまくいくはずです。 –

0

+0

あなたのソリューションは面白いです。しかし、私は一般的な解決策を探しています。カスタム例外クラスのようなもの。各オブジェクト(私は100を超える)のためのバリデータを作成するのはちょっとです。 – danidacar

+0

継承とパラメータを使用して、バリデータを一般化することができます(例えば、バリデーターはすべてのオブジェクトを検証し、クラスをチェックしてから、symfony2を見てください)(http://www.symfony.com /)そのような現実世界の設計の。カスタム例外クラスも同様に行うことができます。しかし、あなたのシナリオでは、複数のExceptionクラスを必要としないと確信しています。 – hakre