ZF2 Form,如何添加自定义验证器

时间:2013-04-03 13:26:09

标签: php zend-framework2

如何在ZF2表单中添加自定义验证器? 我想为zf2表单元素或表单类本身添加一个自定义验证器,以相互验证多个元素。

use Zend\Form\Form;    
class MyForm extends Form {

    public function init()
    {
        // Add some elements
        $this->add(
            $this->getFormFactory()->create(...);
        }

        // How can i add a custom validator here to the form or element?
    }

}

我当前的解决方案

非常简单但有效,表单类或字段集必须实现接口 Zend \ InputFilter \ InputFilterProviderInterface

现在我可以添加这样的内容:

use Zend\Form\Form;
use Zend\InputFilter\InputFilterProviderInterface;
use \PayrollAccountingValidator;
class MyForm extends Form implements InputFilterProviderInterface {

    public function init()
    {
        $this->getFormFactory()->create(
            array(
                    'name' => 'salary',
                    'type' => 'Zend\Form\Element\Number',
                    'attributes' => array(
                            'min' => 0,
                            'step' => 1
                    ),
                    'options' => array(
                            'label' => _('Salary?')
                    )
            ));
    }

    public function getInputFilterSpecification ()
    {
        return array(
                'salary' => array(
                        'validators' => array(
                                new PayrollAccountingValidator($this)
                        )
                )
        );
    }

}

1 个答案:

答案 0 :(得分:3)

我会做什么:

  • 创建表单
  • 创建一个具有验证器依赖关系的输入过滤器
  • 将验证器添加到过滤器
  • 中的字段
  • 将过滤器设置为工厂中的表单。

实施例

形式:

这里我们只是将元素添加到表单中。

class SomeForm extends Form {

   public function __construct() {
        parent::__construct('someform');

        $this->add(array(
            'type' => 'Zend\Form\Element\Textarea',
            'name' => 'somelement',
            'options' => array(
                'label' => 'Message',
            )
        ));
    }
}

过滤器:

这里我们为上述表格中的相关元素创建过滤器。我们在创建输入过滤器时添加在实例化时传入的验证器:

namespace SomeModule\Form;

use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;

class SomeFormFilter implements InputFilterAwareInterface {

    protected $customValidator;

    protected $inputFilter;

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

    public function setInputFilter(InputFilterInterface $inputFilter) {
        throw new \Exception("Not used");
    }

    public function getInputFilter() {
        if (!$this->inputFilter) {

            $inputFilter = new InputFilter();
            $factory = new InputFactory();

            $inputFilter->add(
                $factory->createInput(
                    array(
                        'name' => 'somelement',
                        'required' => true,
                        'filters' => array(array(
                                'name' => 'StringTrim')
                        ),
                        'validators' => array(
                            $this->customValidator
                        ),
                    )
                )
            );

            $this->inputFilter = $inputFilter;
        }

        return $this->inputFilter;
    }
}

Module.php

我们现在可以为表单创建一个工厂来管理过滤器验证器依赖项并将过滤器应用于表单:

public function getServiceConfig() {
     return array(
        'factories' => array(
            'someForm' => function($sm) {
                $form = new SomeForm();
                $validator = new CustomValidator() // or $validator = $sm->get('CustomValidator');
                $formFilter = new SomeFormFilter($validator);
                $form->setInputFilter($formFilter->getInputFilter());
                return $form;
            },
        ),
    );
}

您将需要确保在Module.php中使用正确的命名空间或提供FQCN。

现在您可以使用一行代码在控制器中完全配置此表单:

$form = $this->getServiceLocator()->get('SomeForm');

如果您有任何其他问题,请随时提出。