symfony2学说-将儿童添加到自我相关实体中


symfony2 doctrine - Adding children to self-related Entity

我有一个与自身相关的实体。实体具有字段:

class A
{
    // ...
    /**
     * @var A
     * @ORM'ManyToOne(targetEntity="A", inversedBy="children")
     * @ORM'JoinColumn(name="parent_id", referencedColumnName="id", nullable=true, onDelete="CASCADE")
     */
    protected $parent;
    /**
     * @var A[]
     * @ORM'OneToMany(targetEntity="A", mappedBy="parent", cascade={"all"}, orphanRemoval=true)
     */
    protected $children;
}

我想通过在窗体中设置子项来将子项添加到此实体。此实体类型如下所示:

class AType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            // ...
            ->add('children', 'collection', [
                'type' => new AType(),
                'allow_add' => true,
                'allow_delete' => true,
                'by_reference' => false,
                'prototype' => true,
            ])
        ;
    }
}

当我发送这样的数据时:

'a' => [
    [
        'name' => 'main a',
        'children' => [
            [
                'name' => 'child a 1',
            ],
            [
                'name' => 'child a 2',
            ],
        ],
    ],
],

(在测试中,我没有视图,因为这个应用程序是基于完整的REST-Api通信的)我得到了这个错误:

PHP致命错误:已达到最大函数嵌套级别"100",正在中止!

那么,是否有可能将孩子添加到与自身相关的实体中呢?

如果我有两个实体:实体A和与实体B相关的字段子项,它会起作用。但是,它能处理这种关系吗?

我应该将AType类中的类型new AType()更改为其他类型吗。

编辑:事实上,我只想获取数据并验证它。我不需要HTML表单来显示它。我可以这样做:

// controller
$jms = $this->get('jms_serializer');
$entity = $jms->deserialize($request->getContent(), 'AcmeBundle'Entity'A', 'json');
$this->em->persist($entity);
$this->em->flush();

而无需在控制器中使用Form。但在这种情况下,我的数据不会得到验证。

PHP致命错误:已达到最大函数嵌套级别"100",正在中止!

因为你有递归。当您调用createForm时,它会尝试解析type

您可以在FormFactory函数resolveType中找到这部分代码。

我认为您可以创建第二个表单类型,包括titleparent

class AType extends AbstractType{
   //...
   public function buildForm(FormBuilderInterface $builder, array $options)
   {
    $builder
        ->add('title')
        ->add('parent')
        ->add('children', 'collection', array(
            'type' => new BType(),
            'allow_add' => true,
            'allow_delete' => true,
            'by_reference' => false,
            'prototype' => true
        ));
   }
}
class BType extends AbstractType {
    //..
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
       $builder
         ->add('title')
         ->add('parent');
    }
 }

我认为表单生成器可以获取并映射Content-Type:application/x-www-form-urlencoded。我已经用html表单实现了。我也尝试过发送application/json,但没有成功。这就是为什么您可以在这里使用json模式验证器。

我建议您看看这里:https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/tree.md#tree-实体示例

除了parentID之外,结构id DB还依赖于存储在DB中的其他字段。

它的模型基于此:https://en.wikipedia.org/wiki/Nested_set_model