使用字段集时,ZF2表单无法验证

时间:2016-07-24 15:38:03

标签: php forms validation zend-framework2

我按照ZF2.4手册第12章(介绍我们的第一个“博客”模块),我创建了一个Blog模块。 我有邮寄表格:

class PostForm extends Form{
    public function __construct($name = null, $options = array()){
    parent::__construct($name, $options);

    $this->add(array(
       'name' => 'post-fieldset', 
       'type' => 'Blog\Form\PostFieldset',
        'options' => array(
            'use_as_base_fieldset' => true
        )
      )
    );

    $this->add(array(
        'type' => 'submit',
        'name' => 'submit',
        'attributes' => array(
            'value' => 'Insert new Post',
            'class' => 'btn btn-primary'
        )
    ));
  }
}

和帖子字段集:

class PostFieldset extends Fieldset{
public function __construct($name = null, $options = array()){
    parent::__construct($name, $options);

    $this->setHydrator(new ClassMethods(false));
    $this->setObject(new Post());

    $this->add(array(
        'type' => 'hidden',
        'name' => 'id'
    ));

    $this->add(array(
        'type' => 'text',
        'name' => 'text',
        'options' => array(
            'label' => 'The Text'
        ),
        'attributes' => array(
            'class' => 'form-control'
        )
    ));

    $this->add(array(
        'type' => 'text',
        'name' => 'title',
        'options' => array(
            'label' => 'Blog Title'
        ),
        'attributes' => array(
            'class' => 'form-control'
        )
    ));
}
}

这是我的行动:

public function addAction(){ 
    $request = $this->getRequest();
    if ($request->isPost()) {
        $this->postForm->setInputFilter(new PostFilter());
        $this->postForm->setData($request->getPost());
        if ($this->postForm->isValid()) { 
            echo "The form is valid\n"; 
            //Debug:: dump($this->postForm->getData()); die();
            // save post...
        }else{
            echo "The form is not valid\n"; 
             Debug:: dump($this->postForm->getData()); die();    
        }
    }
    return new ViewModel(array(
        'form' => $this->postForm
    ));
    }

和Post InputFilter:

class PostFilter extends InputFilter {
public function __construct(){
    $title = new Input('title');
    $title->setRequired(true);
    $title->setValidatorChain($this->getTextTitleValidatorChain());
    $title->setFilterChain($this->getStringTrimFilterChain());

    $text = new Input('text');
    $text->setRequired(true);
    $text->setValidatorChain($this->getTextTitleValidatorChain());
    $text->setFilterChain($this->getStringTrimFilterChain());

    $this->add($title);
    $this->add($text);
    }
 protected function getTextTitleValidatorChain(){
    $notEmpty = new NotEmpty();
    $stringLength = new StringLength();
    $stringLength->setMin(5);
    $stringLength->setMax(20);

    $validatorChain = new ValidatorChain();
    $validatorChain->attach($notEmpty);
    $validatorChain->attach($stringLength);

    return $validatorChain;
}
protected function getStringTrimFilterChain(){
    $filterChain = new FilterChain();
    $filterChain->attach(new StringTrim());

    return $filterChain;
}
}

和add.phtml视图:

<?php 
 $form = $this->form;
 $form->setAttribute('action', $this->url());
 $form->prepare();
 echo $this->form()->openTag($form);
?>
<div class="form-group" >
  <?php echo $this->formRow($form->get('post-fieldset')->get('title')); ?>
</div>

<div class="form-group" >
  <?php echo $this->formRow($form->get('post-fieldset')->get('text')); ?>
</div>
<?php echo $this->formSubmit($form->get('submit')); ?>
<?php echo $this->form()->closeTag(); ?>

如果我提交表单,表单错误不会显示。 此外,如果我输入有效数据,我会看到如下数据转储:

 The form is not valid
array(4) {
   ["title"] => NULL
   ["text"] => NULL
   ["submit"] => string(15) "Insert new Post"
 ["post-fieldset"] => array(3) {
   ["id"] => NULL
   ["text"] => string(7) "my text"
   ["title"] => string(8) "my title"
 }
}

数据未水合成Post对象,转储数据显示两个标题和两个文本和字段集名称,我不明白。 如果我删除$this->postForm->setInputFilter(new PostFilter());数据水合物到Post对象。

为什么验证不起作用,表单错误没有显示,为什么数据没有融入Post对象?

1 个答案:

答案 0 :(得分:0)

我只能将您重定向到文档: https://framework.zend.com/manual/2.3/en/modules/zend.input-filter.intro.html

要恢复:

  • 你不能像这样声明一个新的InputFilter对象,这将创建新的输入,但你的对象已经有了它们。所以这就是你在var_dump
  • 中拥有它们的原因
  • 我建议您使用此方法在Fieldset的对象中使用InputFilterProviderInterfacepublic function getInputFilterSpecification()在那里您可以设置过滤器和验证器,因为您的控制器没有任何变化,您将拥有一个更简单的代码 docs:https://framework.zend.com/manual/2.0/en/modules/zend.form.quick-start.html#hinting-to-the-input-filter

您的验证无法正常工作,因为您的输入过滤器导致水合作用失败。

编辑:

我看到了你的意见,我不同意这里的原因:

 $this->add(array(
       'name' => 'post-fieldset', 
       'type' => 'Blog\Form\PostFieldset',
        'options' => array(
            'use_as_base_fieldset' => true
        )
      )
    );

执行此操作时,您告诉您的表单添加一些字段,并且由于您没有设置验证组,因此il将为validate_all。但是当你在你的控制器中添加你的班级PostFilter时,你又添加了新的输入,所以你将有2个输入标题和2个输入文本,一个带有水合器的字段集,一个没有水合器。这就是为什么你对fieldset的输入加水,你的其他输入失败,因为你的inputfilter类的验证器失败了!

正如我所说,尝试我的解决方案,看看会发生什么。

此链接可帮助您了解PostFilter未正确配置到表单中的原因: Adding input filter to fieldset in ZF2