使用AnnotationReader创建的Zend Framework 2表单即使在数据无效时也是有效的

时间:2012-12-15 09:55:15

标签: php zend-form zend-framework2

我有一个Form,我使用这样的注释构建器创建:

$builder  = new AnnotationBuilder();
$fieldset = $builder->createForm(new \Application\Entity\Example());  
$this->add($fieldset);
$this->setBaseFieldset($fieldset);

在控制器中,一切都是标准的:

$entity = new \Application\Entity\Example();
$form = new \Application\Form\Example();
$form->bind($entity);
if($this->getRequest()->isPost()) {
    $form->setData($this->getRequest()->getPost());
    if($form->isValid()) {
        // save ....
    }
}

问题是,$ form-> isValid()始终返回true,即使提交了空或无效表单也是如此。更奇怪的是表单元素错误消息都已设置,暗示它们无效。

我查看了ZF2 Form / InputFilter / Input类,发现: 输入> isValid()被调用两次:一次在Form-> isValid()中,一次在Form-> bindValues()中 在第一次调用中,Input-> isValid()($ this-> getValidatorChain)中的验证器链为空,在第二次调用中(来自bindValues),它是正确的。

可能出现什么问题?

PS。使用devel版本2.1

2 个答案:

答案 0 :(得分:1)

我发现了导致它的原因。

事实证明,注释构建器从未打算以这种方式工作。注释构建器创建一个\ Zend \ Form \ Form实例,我将其作为基本形式的字段集放置。我不知道为什么,但这导致基本形式无法验证。所以为了使上面的代码工作,应该没有额外的Form类,在控制器中我们应该有:

$entity = new \Application\Entity\Example();
$builder  = new AnnotationBuilder();
$form = $builder->createForm($entity);  
$form->bind($entity);
if($this->getRequest()->isPost()) {
    $form->setData($this->getRequest()->getPost());
    if($form->isValid()) {
        // save ....
    }
}

将来可能会在AnnotationBuilder中有一个createFieldset函数,但是现在这似乎是唯一的方法。希望这有助于某人。 :)

答案 1 :(得分:0)

我也遇到了同样的问题。当我使用Annotations在表单中创建Fieldsets @Annotation \ Type(“fieldset”)时, isValid()始终返回true。

查看 Zend \ Form \ Factory 的代码,当我们创建一个Fieldset时, configureFieldset()函数不会调用 prepareAndInjectInputFilter(),即使有 input_filter 作为表单规范的一部分。

只有在我们创建表单时, Zend \ Form \ Factory :: configureForm()函数才会调用 prepareAndInjectInputFilter()

因此,当 type 设置为创建表单时,输入过滤器和验证组似乎只由AnnotationBuilder创建。

我自己创建了一个输入过滤器,通过将以下代码添加到我的表单中来注释:

    $fspec = ArrayUtils::iteratorToArray($builder->getFormSpecification($entity));
    $outerfilter = new InputFilter();
    $iffactory = new \Zend\InputFilter\Factory ();
    $filter  = $iffactory->createInputFilter($fspec['input_filter']);
    $outerfilter->add($filter, 'shop');  // Use the name of your fieldset here.
    $this->setInputFilter($outerfilter);