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()

例如,脚本返回以下值

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

基本上,我将创建一个数组,根据每个函数的结果用真/假填充它,然后我将在数组中查找特定值(假)。如果存在,则无论链的其余部分如何,该类都将返回 false。(或者我可以覆盖变量,在这里并不重要。)

但是,我希望 $validator 一旦从函数中获得 false 就停止链接。假设它从 isSet() 收到了错误。它不应该执行 isNull() 和 getResult() 因为我们已经有一个失败的检查。

我怎样才能在 PHP 中归档它?

TL;博士:

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

没有什么比好的源代码更值得学习的了。我建议探索 Zend 框架的验证类。它提供了与您描述的相同的链接功能。

...更多源代码检查 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();

Foo() 部分不会被执行,因为 Bar() 中的异常。

当然,也有一些变化。如果你不想要一个异常,而是一个静默的非执行,你可以试试这个:

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 中是可能的,所以最好使用 Exceptions

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

考虑到在链的每个步骤中返回的值都是一个对象,您不能让一个链式方法返回 true/false。它必须始终返回一个对象实例。所以我猜你需要做的是在对象上添加一些属性以指示不应该进行验证,如果设置了属性,则忽略验证尝试并按原样返回对象。

所以也许像这样的简化形式,只显示一个这样的验证:

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 回答