如何从 Zend Forms 中正确地混合和提取 Doctrine Entities
How to properly hydrate and extract Doctrine Entities from Zend Forms
我刚开始使用 Doctrine,正在重写一些代码以在某些 Forms 中使用 Doctrine 实体。
我有一个实体业务,它与地址、员工、电子邮件等有一些 1:n 关系。设置非常基本并且运行良好。
为了添加新业务,我为每个实体创建了一个 BusinessForm 和 Fieldset。这里是表单的构造函数:
public function __construct($scenario='create', $entityManager = null) {
parent::__construct('business_form');
$this->scenario = $scenario;
$this->entityManager = $entityManager;
$this->setAttribute('method', 'post');
$businessFieldset = new BusinessFieldset($this->entityManager);
$businessFieldset->setUseAsBaseFieldset(true);
$this->add($businessFieldset);
$hydrator = new DoctrineHydrator($this->entityManager, new Business());
$this->setHydrator($hydrator);
$this->addElements();
$this->addInputFilter();
}
addElements 只是添加一个提交和 CSRF 输入。
这里是控制器操作:
public function addAction(){
$form = new BusinessForm('create', $this->entityManager);
if ($this->getRequest()->isPost()) {
$data = $this->params()->fromPost();
$form->setData($data);
if($form->isValid()) {
// save Object
return $this->redirect()->toRoute('subcontractor', ['action'=>'index']);
}
}
return new ViewModel([
'form' => $form
]);
}
表单通过验证,我可以使用 $form->getData()
从表单中获取数据。但是我无法弄清楚如何使用表单的水化器从表单中获取填充的对象。当我在控制器开始时使用 setObject(new Business())
时出现错误,而 $form->isValid()
是 运行 :
Zend\Hydrator\ArraySerializable::extract expects the provided object to implement getArrayCopy()
是不是叫错了水龙头?
如果我不 setObject()
而是在验证后使用 $form->bind(new Business())
,我会从 $form->getObject()
得到一个空对象。如果我获取数据并像这样使用表单的水化器水合一个新对象:$form->getHydrator()->hydrate($data['business], new Business())
我确实得到了我期望的填充对象。 (业务是基础字段集的名称)
所以我的问题是,如何在验证后仅使用 $form->getObject()
获得最后一次调用的结果?
[编辑]
问题似乎出在业务字段集中用作子字段集的字段集集合。如果我在不使用集合的情况下验证表单,我确实会从 $form->getData()
获得预期的业务对象
这是我如何添加集合(在业务字段集中)的示例:
$this->add([
'name' => 'emails',
'type' => 'Zend\Form\Element\Collection',
'attributes' => [
'id' => 'business_emails',
],
'options' => [
'label' => 'Emails',
'count' => 1,
'should_create_template' => true,
'template_placeholder' => '__index__',
'allow_add' => true,
'target_element' => [
'type' => 'LwsSubcontractor\Form\EmailFieldset',
],
'target_class' => 'LwsSubcontractor\Entity\Email'
],
]);
这里是 EmailFieldset:
public function __construct() {
parent::__construct('email');
$this->setObject(new Email());
$this->addElements();
}
protected function addElements() {
$this->add([
'name' => 'email',
'type' => 'Zend\Form\Element\Email',
'attributes' => [
'placeholder' => 'E-Mail (z.B. email@muster-email.de)',
'class' => 'form-control',
'required' => true,
'size' => 50,
],
'options' => [
'label' => 'Email',
],
]);
}
}
如果使用集合,我会收到上面的错误消息。因此,在为每个 Fieldset 添加一个保湿器后,我很好。
虽然我的印象是为表单设置水化器会导致使用的字段集继承hydrator.Or这是因为将字段集用作集合而不是直接使用吗?
你必须将 hydrator 添加到你所有的字段集中,我个人使用 DoctrineModule\Stdlib\Hydrator\DoctrineObject
作为学说实体。
我还会考虑使用 init()
方法来初始化您的表单并添加元素,然后通过 FormElementManager $serviceLocator->get('FormElementManager')->get(yourFieldsetorForm::class)
注册和检索您的表单和字段集。然后可以将表单注入到您的控制器中。
希望对您有所帮助。
我刚开始使用 Doctrine,正在重写一些代码以在某些 Forms 中使用 Doctrine 实体。
我有一个实体业务,它与地址、员工、电子邮件等有一些 1:n 关系。设置非常基本并且运行良好。
为了添加新业务,我为每个实体创建了一个 BusinessForm 和 Fieldset。这里是表单的构造函数:
public function __construct($scenario='create', $entityManager = null) {
parent::__construct('business_form');
$this->scenario = $scenario;
$this->entityManager = $entityManager;
$this->setAttribute('method', 'post');
$businessFieldset = new BusinessFieldset($this->entityManager);
$businessFieldset->setUseAsBaseFieldset(true);
$this->add($businessFieldset);
$hydrator = new DoctrineHydrator($this->entityManager, new Business());
$this->setHydrator($hydrator);
$this->addElements();
$this->addInputFilter();
}
addElements 只是添加一个提交和 CSRF 输入。
这里是控制器操作:
public function addAction(){
$form = new BusinessForm('create', $this->entityManager);
if ($this->getRequest()->isPost()) {
$data = $this->params()->fromPost();
$form->setData($data);
if($form->isValid()) {
// save Object
return $this->redirect()->toRoute('subcontractor', ['action'=>'index']);
}
}
return new ViewModel([
'form' => $form
]);
}
表单通过验证,我可以使用 $form->getData()
从表单中获取数据。但是我无法弄清楚如何使用表单的水化器从表单中获取填充的对象。当我在控制器开始时使用 setObject(new Business())
时出现错误,而 $form->isValid()
是 运行 :
Zend\Hydrator\ArraySerializable::extract expects the provided object to implement getArrayCopy()
是不是叫错了水龙头?
如果我不 setObject()
而是在验证后使用 $form->bind(new Business())
,我会从 $form->getObject()
得到一个空对象。如果我获取数据并像这样使用表单的水化器水合一个新对象:$form->getHydrator()->hydrate($data['business], new Business())
我确实得到了我期望的填充对象。 (业务是基础字段集的名称)
所以我的问题是,如何在验证后仅使用 $form->getObject()
获得最后一次调用的结果?
[编辑]
问题似乎出在业务字段集中用作子字段集的字段集集合。如果我在不使用集合的情况下验证表单,我确实会从 $form->getData()
这是我如何添加集合(在业务字段集中)的示例:
$this->add([
'name' => 'emails',
'type' => 'Zend\Form\Element\Collection',
'attributes' => [
'id' => 'business_emails',
],
'options' => [
'label' => 'Emails',
'count' => 1,
'should_create_template' => true,
'template_placeholder' => '__index__',
'allow_add' => true,
'target_element' => [
'type' => 'LwsSubcontractor\Form\EmailFieldset',
],
'target_class' => 'LwsSubcontractor\Entity\Email'
],
]);
这里是 EmailFieldset:
public function __construct() {
parent::__construct('email');
$this->setObject(new Email());
$this->addElements();
}
protected function addElements() {
$this->add([
'name' => 'email',
'type' => 'Zend\Form\Element\Email',
'attributes' => [
'placeholder' => 'E-Mail (z.B. email@muster-email.de)',
'class' => 'form-control',
'required' => true,
'size' => 50,
],
'options' => [
'label' => 'Email',
],
]);
}
}
如果使用集合,我会收到上面的错误消息。因此,在为每个 Fieldset 添加一个保湿器后,我很好。
虽然我的印象是为表单设置水化器会导致使用的字段集继承hydrator.Or这是因为将字段集用作集合而不是直接使用吗?
你必须将 hydrator 添加到你所有的字段集中,我个人使用 DoctrineModule\Stdlib\Hydrator\DoctrineObject
作为学说实体。
我还会考虑使用 init()
方法来初始化您的表单并添加元素,然后通过 FormElementManager $serviceLocator->get('FormElementManager')->get(yourFieldsetorForm::class)
注册和检索您的表单和字段集。然后可以将表单注入到您的控制器中。
希望对您有所帮助。