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

Php 使用AnnotationReader创建的Zend Framework 2表单即使在数据无效时也有效,php,zend-form,zend-framework2,Php,Zend Form,Zend Framework2,我有一个表单,我使用注释生成器创建它,如下所示: $builder = new AnnotationBuilder(); $fieldset = $builder->createForm(new \Application\Entity\Example()); $this->add($fieldset); $this->setBaseFieldset($fieldset); 在控制器中,一切都是标准的: $entity = new \Application\Entity\

我有一个表单,我使用注释生成器创建它,如下所示:

$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表单/InputFilter/Input类,发现: Input->isValid()被调用两次:一次在表单->isValid()中调用,一次在表单->bindValues()中调用 在第一次调用中,Input->isValid()($this->getValidatorChain)中的验证器链是空的,在第二次调用中(来自bindValues),它是正确的

可能出了什么问题


另外,使用develversion2.1,我找到了导致它的原因

事实证明,注释生成器从未打算以这种方式工作。注释生成器创建一个\Zend\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函数,但目前这似乎是唯一的方法。希望这对某人有帮助。:)

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

查看Zend\Form\Factory的代码,在创建字段集时,configureFieldset()函数不会调用prepareAndInjectInputFilter(),即使表单规范中有输入过滤器

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

因此,输入过滤器和验证组似乎仅由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);