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