2011-10-23 8 views
4

メソッドチェインを使用する検証クラスがあります。問題は、しかし、もし一つの方法は、FALSEを返すということです、それはないでしょうメソッドをチェーンするときにfalseを返す方法

if ($obj->checkSomething()->checkSomethingElse()) {} 

:私はこのようなTRUE/FALSEで単一のチェックを行うことができるようにしたいと思います:

if ($obj->checkSomething()) {} 

しかし、また、このようなチェーン方法オブジェクトを返送し、このエラーで終了するメソッド連鎖を解除します。

Fatal error: Call to a member function checkSomething() on a non-object in ... 

いずれかの方法を選択する必要がありますか?解決法がありますか?

+2

これは、私がそれを打ち負かすためにメソッドチェーンを使用しないでください理由の良い記号です: – NikiC

答えて

8

1つの考え方は、成功または失敗を示す内部フラグを設定し、別の方法でアクセスすることです。各メソッドでそのフラグをチェックし、設定されていれば何もしません。例えば:

class A { 
    private $valid = true; 

    public function check1() { 
     if (!$this->valid) { 
      return $this; 
     } 
     if (!/* do actual checking here */) { 
      $this->valid = false; 
     } 
     return $this; 
    } 
    public function check2() { 
     if (!$this->valid) { 
      return $this; 
     } 
     if (!/* do actual checking here */) { 
      $this->valid = false; 
     } 
     return $this; 
    } 
    public function isValid() { 
     return $this->valid; 
    } 
} 

// usage: 

$a = new A(); 

if (!$a->check1()->check2()->isValid()) { 
    echo "error"; 
} 

は、各機能のチェックイン定型を最小限に抑えるために、あなたもマジックメソッド__call()を使用することができます。例えば:

class A { 
    private $valid; 
    public function __call($name, $args) { 
     if ($this->valid) { 
      $this->valid = call_user_func_array("do" . $name, $args); 
     } 
     return $this; 
    } 
    private function docheck1() { 
     return /* do actual checking here, return true or false */; 
    } 
    private function docheck2() { 
     return /* do actual checking here, return true or false */; 
    } 
    public isValid() { 
     return $this->valid; 
    }  
} 

使用量は上記と同じで、次のようになります。

$a = new A(); 

if (!$a->check1()->check2()->isValid()) { 
    echo "error"; 
} 
+0

+1。 –

+0

これについて考えてみましたが、おそらく問題を処理する簡単な方法を望んでいました。 PHPの専門家が簡単な解決策を提示するかどうかを確認します。そうしないと答えが受け入れられます。ありがとう! – Seralize

1

私はあなたがインスタンスを持っているために探していると考えているが、検証の結果に基づいて、偽/真を評価します。

インスタンスのブール値をオーバーライドできる言語もありますが、PHPは文字列へのキャスト以外はありません(PHPのMagic Methodsを参照)。

また、PHPマニュアルのthe booleans pageには、falseと評価されるもののリストがありますが、動作を上書きする方法もありません。

これは、JRLの考え方に沿って検証ルールのチェーンを構築し、ifステートメントで必要なブール値を返す関数で '実行'することをお勧めします。

0

おそらくサブクラスでそれらを包むことができます。

クイックや汚れ

class ValidateChain extends Validate { 
    protected $valid = true; 

    public function checkSomething($data) { 
     if (false === parent::checkSomething($data)) { 
      $this->valid = false; 
     } 
     return $this; 
    } 
    public function checkSomethingElse($data) { 
     if (false === parent::checkSomethingElse($data)) { 
      $this->valid = false; 
     } 
     return $this; 
    } 
    public function getIsValid() { 
     return $this->valid; 
    } 
} 

$v = new ValidationChain(); 
$valid = $v->checkSomething()->checkSomethingElse()->getIsValid(); 

、E & OE:あなたは

class Validate { 
    public function checkSomething($data) { 
     if ($data === $valid) { 
      return true; 
     } 
     return false; 
    } 
    public function checkSomethingElse($data) { 
     if ($data === $valid) { 
      return true; 
     } 
     return false; 
    } 
} 

を持っている場合は、これを行うことができます。そして、おそらくどのビットが有効でないか調べる方法を追加する必要があります。

関連する問題