【问题标题】:How to properly hydrate and extract Doctrine Entities from Zend Forms如何从 Zend Forms 中正确地补充和提取 Doctrine Entity
【发布时间】:2017-09-01 08:43:43
【问题描述】:

我刚刚开始使用 Doctrine,并且正在重写一些代码以在某些 Forms 中使用 Doctrine 实体。

我有一个实体业务,它与地址、员工、电子邮件等有一些 1:n 关系。设置非常基本并且工作正常。

为了添加新业务,我为我的每个实体创建了一个 BusinessForm 和 Fieldsets。这里是表单的构造函数:

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 添加水合器之后,我就很好了。

虽然我的印象是为表单设置水合器会导致使用的字段集继承该水合器。或者这是因为将字段集用作集合而不是直接使用?

【问题讨论】:

    标签: doctrine zend-form zend-framework3 hydration


    【解决方案1】:

    您必须将水合器添加到您的所有字段集中,我个人使用 DoctrineModule\Stdlib\Hydrator\DoctrineObject 表示教义实体。

    我还会考虑使用init() 方法来初始化您的表单并添加元素,然后通过FormElementManager $serviceLocator->get('FormElementManager')->get(yourFieldsetorForm::class) 注册和检索您的表单和字段集。然后可以将表单注入到您的控制器中。

    我希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-05
      • 1970-01-01
      • 2012-01-19
      • 2018-10-06
      相关资源
      最近更新 更多