1

フォーム検証クラスを作成していますが、現在このように機能しています。

$validator->setVar($_POST['Username'])
          ->standardFilter(array('XSS', 'SQL_INJECTION'))
          ->customRegex()
          ->replace('This', 'With this')
          ->getResult();

このように連鎖すると完全に機能しますが、次の結果をアーカイブすることはできません。

$validator->setVar($_POST['Username'])
          ->isValidEmail()
          ->isValidPhoneNumber()
          ->isSet()
          ->isNull()
          ->getResult()

たとえば、scriptは次の値を返します

->isValidEmail() (true)
->isValidPhoneNumber() (true)
->isSet() (false)

基本的には、配列を作成し、各関数の結果に応じてtrue / falseで埋め、配列内の特定の値(false)を探します。存在する場合、残りのチェーンに関係なく、クラスはfalseを返します。(または、変数をオーバーライドすることもできますが、ここでは重要ではありません。)

ただし、関数からfalseを取得したら、$validatorがチェーンを停止するようにします。isSet()からfalseを受け取ったとしましょう。すでにチェックに失敗しているため、isNull()とgetResult()を実行しないでください。

これをPHPでアーカイブするにはどうすればよいですか?

TL; DR:

var_dump($validator->setVar('Test message')->isInteger()->setTrue());
                                             //false     //true

Output: false, because once isInteger() failed, rest of the chain isn't executed.

これをPHPでアーカイブするにはどうすればよいですか?

4

5 に答える 5

5

学ぶべき良いソースコードのようなものはありません。ZendFrameworkのValidationクラスを調べることをお勧めします。それはあなたが説明するのと同じ連鎖機能を提供します。

...より多くのソースコードは特にisValid()をチェックします。

于 2012-09-11T18:06:09.063 に答える
2

このようなものを試してください

class FooBar
{
  private $SomethingWrong = false;

  function Bar()
  {
    if( $this->SomethingWrong )
      throw new Exception('SomeThing is wrong');
    return $this;
  }

  function Foo()
  {
    return $this
  }
}

$foobar = new FooBar();
$foobar->Bar()
       ->Foo();

Bar()の例外のため、Foo()部分は実行されません。

もちろん、いくつかのバリエーションがあります。例外は必要ないが、サイレントに実行しない場合は、次のことを試すことができます。

class FooBar
{
  private $SomethingWrong = false;

  function Bar()
  {
    $this->SomethingWrong = true;
    return $this;
  }

  function Foo()
  {
    if( !$this->SomethingWrong )  {
      // do my stuff
    }
    return $this
  }
}
于 2012-09-11T18:01:31.217 に答える
2

これを行う唯一の方法は、どの言語でも、例外をスローすることです。チェーンが機能している間は、バリデーターオブジェクト(チェーンに必要)を返すことも、trueまたはfalseを返すこともできません。とはいえ、私はこのように例外を使用することを推奨していません。私は以下のvascowhiteのコメントに完全に同意します。

チェーンの途中で停止させるのではなく、バリデーターに何をチェックするかを指示するための指示として、、などのメソッドをisSet検討してみませんか。isNull次にvalidate、チェーンの最後でメソッドを呼び出します。このvalidateメソッドは、(他のメソッドによって設定された)バリデーターの状態に基づいて検証を実行できます。また、そのvalidateメソッドは、検証の結果とともに、trueまたはfalse、あるいはカスタム状態オブジェクトを返すこともできます。

于 2012-09-11T18:11:52.483 に答える
1

値を返す代わりに、コードの実行を中止するカスタム例外をスローできます。コードにtry-catchブロックを追加し、例外を処理すれば、すべてが正常に機能します。

編集:あなたもできることは少し魔法であり、実際にはお勧めできません。ただし、これはphpで可能であるため、例外を使用することをお勧めします。

class PassThroughValidator extends ...
{
    private $val;

    public function __construct($result)
    {
        $this->val = $result;
    }

    public function __call($name, $arguments)
    {
        return $this;
    }

    public function getResult()
    {
        return $this->val;
    }
}

class EmailValidator extends ...
{

    function isMail()
    {
        if (...) {
            // do something here
            return $this;
        }

        // set Result to false or something similar
        return new PassThroughValidator($this->getResult());
    }
}
于 2012-09-11T18:01:49.080 に答える
0

チェーンの各ステップで返される値がオブジェクトであることを考慮すると、チェーンされたメソッドの1つにtrue/falseを返すことはできません。常にオブジェクトインスタンスを返す必要があります。したがって、検証を実行しないようにオブジェクトにプロパティを追加する必要があると思います。プロパティが設定されている場合は、検証の試行を無視して、オブジェクトをそのまま返します。

したがって、おそらくこのような単純化された形式で、そのような検証を1つだけ示します。

class validator {
    protected $ignore_validations = false;
    protected $value = null;
    protected $is_null;

    public function isNull () {
        if(true === $this->ignore_validations) {
            return $this;
        } else if(is_null($this->value)) {
            $this->is_null = true;
            $this->ignore_validations = true;
            return $this;
        } else {
            $this->is_null = false;
            return $this;
        }
    }
}
于 2012-09-11T18:09:09.937 に答える