Как проверить поле Zend_Form на основе значения другого поля?

#php #zend-framework #zend-form #zend-validate

#php #zend-framework #zend-form #zend-проверка

Вопрос:

Я пытаюсь добавить пользовательский валидатор в поле. Оно должно учитывать значение другого поля. Например. поле A должно быть не более B 50%.

Я создал реализацию класса Zend_Validate_Interface , но, по-видимому, Zend Form отправляет только значение текущего поля в средство проверки. Как мне заставить средство проверки получать все?

Ответ №1:

При вызове isValid a Zend_Form он передаст все данные, которые вы передали методу

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

Ваш пользовательский валидатор получит весь этот массив необработанных значений.

Пример валидатора

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

Пример формы

 $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));
  

Вывод

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

Как вы можете видеть, был также передан второй аргумент isValid , который является $context . И это содержит остальные значения.

Альтернативой было бы передать второй элемент для сопоставления в качестве опции в средство проверки, например

 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;
    }
}
  

Настройка

 $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));
  

Затем будет напечатан int(1) . Как вы можете видеть, мы извлекли это значение через API элемента формы, поэтому будет применено все, что вы настроили для валидаторов и фильтров, например, это не исходное значение. И вы также можете установить для него другое значение и т.д.

Также посмотрите Zend_Validate_Identical , чтобы узнать, как ZF реализует проверку других элементов формы:

Комментарии:

1. Ну, я думаю, что вы ошибаетесь с первой частью. Вы вызываете isValid $b вместо $f . Я проверил это перед отправкой, и вызов isValid формы не отправляет все данные элементам isValid . Читаем дальше ответ — он довольно большой)

2. @Fluffy виноват, извините. Тем не менее, это правильно. Смотрите мое обновление. Полный массив будет находиться в $context .

3. На самом деле вы правы. Понятия не имею, почему об этом нет упоминания в документации Zend_Validate_Interface. Спасибо, я думаю, это то, что я искал

4. @Fluffy Я предполагаю, что это потому, что это нарушило бы обратную совместимость, если бы они изменили подпись isValid в интерфейсе. Все валидаторы, реализующие это, должны были бы изменить свои методы, чтобы включить $context, а затем соответствовать определению интерфейса.