Zend Framework 2表单未绑定对象时Fieldset数据获取异常排查
嘿,我一眼就看出问题出在哪了——你创建了Fieldset,但没有把它添加到Form实例里!这就是为什么表单生成的input标签name是input2而不是field1[input2],进而导致getData()里的field1数组拿不到正确值。
1. 修正表单代码:将Fieldset添加到Form中
你需要在创建Fieldset后,调用$form->add()把它关联到表单。修正后的代码如下:
$form = new Form(); $form->add( [ 'name' => 'input1', 'type' => 'Text', ] ); $fieldset1 = new Fieldset(); $fieldset1->setName('field1'); $fieldset1->add( [ 'name' => 'input2', 'type' => 'Text', ] ); // 关键步骤:把字段集添加到表单中 $form->add($fieldset1);
2. 为什么这能解决问题?
Zend Framework 2的Fieldset必须依附于Form(或另一个Fieldset)才能正常工作。当Fieldset被添加到Form后,渲染表单时会自动给Fieldset内的所有元素加上字段集名称作为前缀,生成的input标签name会变成field1[input2]——和你手动构造的格式一致。这样当你提交表单时,$request->getPost()的数据结构会和Form的结构匹配,setData()就能正确映射数据,getData()自然就能拿到field1下的input2值了。
3. 获取经过过滤和验证的Fieldset数据
如果需要对Fieldset内的字段做过滤和验证,你需要给Fieldset绑定对应的InputFilter,再把这个InputFilter关联到Form的InputFilter中。示例代码如下:
给Fieldset添加InputFilter
// 创建Fieldset的InputFilter $fieldsetInputFilter = new InputFilter(); $fieldsetInputFilter->add([ 'name' => 'input2', 'required' => true, 'filters' => [ ['name' => 'StringTrim'], // 去除首尾空格 ['name' => 'StripTags'], // 去除HTML标签 ], 'validators' => [ ['name' => 'NotEmpty', 'options' => [ 'messages' => ['isEmpty' => 'input2不能为空'] ]], ], ]); // 绑定到Fieldset $fieldset1->setInputFilter($fieldsetInputFilter);
给Form关联Fieldset的InputFilter
// 创建Form的InputFilter $formInputFilter = new InputFilter(); // 将Fieldset的InputFilter以字段集名称为键添加进去 $formInputFilter->add($fieldsetInputFilter, 'field1'); // 给Form设置InputFilter $form->setInputFilter($formInputFilter);
当表单验证通过后,你就可以通过$data['field1']['input2']拿到经过过滤和验证后的正确值了。
测试验证
修正代码后,重新渲染表单,你会发现input2的name属性变成了field1[input2]。提交表单后,var_dump($data)的输出里,field1数组下的input2就会是你提交的'b'值,而不再是null。
内容的提问来源于stack exchange,提问作者Tomek Kobyliński

