ZF2 +原则2:通过ZF2形式水合物相关物体


ZF2 + Doctrine 2: Hydrate related objects via ZF2 Form

我们的应用程序(Zend Framework 2 + Doctrine 2)有一个引用其相关对象(如BillingAddress等)的Order实体。我们已经实现了一个REST API来创建和更新订单。数据作为关联数组传递给这个API,被引用对象的数据可以封装在这个数组中。即Order API接收到的数据看起来像这样

$data = [
    // This is an attribute of the Order entity itself
    'remarks' => 'Urgent order', 
    // This is the data of the referenced BillingAddress
    'billing_address' => [
        'firstname' => 'Barry',
        'lastname' => 'Fooman'
    ]
];

首先要注意的是,给定的BillingAddress可以是新的,也可以是现有的!在后一种情况下,id将成为billing_address数据的一部分。

使用DoctrineObject水合器

$hydrator = new DoctrineObject($entityManager);
$hydrator->hydrate($order, $data);
Doctrine负责自动更新或创建被引用的对象。到目前为止,我们是这样做的:获取接收到的数据,做一些处理来消毒和验证数据,并调用水合器。

然而,我们现在想使用Zend'Form'Form来方便地对接收到的数据进行消毒。为Order的简单属性设置Form非常简单

class OrderForm
    extends 'Zend'Form'Form
{
    public function __construct()
    {
        parent::__construct('order');
        $this
            ->add([
                'name' => 'remarks',
                'type' => 'text'
            ]);
    }
}

但是我与引用的对象斗争。我如何设置的形式,使引用的对象被创建或更新的原则,就像使用水合器直接?我必须创建一个"子表单/字段集"吗?

是的,您可以为BusinessAddress实体创建一个字段集,然后将其添加到OrderForm。

use Zend'Form'Fieldset;
class BusinessAddressFieldset extends Fieldset
{
  public function __construct($entityManager)
{
    parent::__construct('businessAddress');
    $this->add(array(
        'name' => 'firstName',
        'type' => 'Zend'Form'Element'Text',
        'options' => array(
            'label' => 'First Name',
        ),
        'attributes' => array(
            'type' => 'text',
        ),
    ));
    $this->add(array(
        'name' => 'lastName',
        'type' => 'Zend'Form'Element'Text',
        'options' => array(
            'label' => 'Last Name',
        ),
        'attributes' => array(
            'type' => 'text',
        ),
    ));
}
}

然后将字段集添加到您的OrderForm:

class OrderForm
extends 'Zend'Form'Form
{
    public function __construct()
    {
        parent::__construct('order');
        // add fields
        $this->add(new BusinessAddressFieldset()); 
    }
}

确保您设置的字段集的名称与引用的名称相匹配,并且您设置了表单hydrator