How to validate a field of Zend_Form based on the

2019-05-14 17:29发布

问题:

I'm trying to add a custom validator to a field. It should take into account the value of another field. E.g. field A should be at most B+50%.

I've made a class implementing Zend_Validate_Interface, but apparently Zend Form only sends in the value of the current field to the validator. How do I make the validator receive everything?

回答1:

When you call isValid on a Zend_Form it will pass the all the data you passed to the method

$form->isValid(array('a' => 1, 'b' => 2));

Your custom validator will receive that whole array of raw values.

Example Validator

class My_Validator_TwoVals implements Zend_Validate_Interface
{
    public function getMessages()
    {
        return array();
    }
    public function isValid($value)
    {
        print_r(func_get_args());
    }
}

Example Form

$f = new Zend_Form;
$a = $f->createElement('Text', 'a');
$b = $f->createElement('Text', 'b');
$b->addPrefixPath('My_Validator', '.', 'validate');
$b->addValidator('TwoVals');
$f->addElements(array($a, $b));

$f->isValid(array('a' => 1, 'b' => 2));

Output

Array
(
    [0] => 2
    [1] => Array
        (
            [a] => 1
            [b] => 2
        )
)

As you can see there was also a second argument passed to isValid, which is $context. And that contains the remaining values.

An alternative would be to pass the second element to match against as an option to the Validator, e.g.

class My_Validator_TwoVals implements Zend_Validate_Interface
{
    protected $a;
    public function getMessages()
    {
        return array();
    }
    public function isValid($value)
    {
        var_dump($this->a->getValue());
    }
    public function __construct(Zend_Form_Element $a)
    {
        $this->a = $a;
    }
}

Setup

$f = new Zend_Form;
$a = $f->createElement('Text', 'a');
$b = $f->createElement('Text', 'b');
$b->addPrefixPath('My_Validator', '.', 'validate');
$b->addValidator('TwoVals', false, array($a));
$f->addElements(array($a, $b));

$f->isValid(array('a' => 1, 'b' => 2));

Will then print int(1). As you can see, we fetched that value through the form element's API so anything you configured for validators and filters would be applied, e.g. it's not the raw value. And you can also set it to another value, etc.

Also have a look at Zend_Validate_Identical to learn how ZF implements checking of other form elements:

  • http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Validate/Identical.php