【问题标题】:symfony2 doctrine - Adding children to self-related Entitysymfony2 教义 - 将子项添加到自相关实体
【发布时间】:2015-11-16 17:01:15
【问题描述】:

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

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”的最大函数嵌套级别,正在中止!

那么,甚至可以将子级添加到自相关实体中吗?

如果我有 2 个实体,它会起作用:实体 A 的子字段与实体 B 相关。但是,它可以与这种关系一起使用吗?

我是否应该将 AType 类中的 typenew AType() 更改为不同的东西。

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

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

$this->em->persist($entity);
$this->em->flush();

在控制器中不使用表单。但在这种情况下,我的数据不会被验证。

【问题讨论】:

  • 您是否正在尝试序列化您的实体?自引用可能会导致这种情况,您需要实现自己的序列化规则。
  • 没有。我只是尝试添加这个,就是这样。我在控制器中的操作看起来完全正常并返回空响应。
  • 尝试increase the xdebug valuexdebug.max_nesting_level = 200。它应该给你真正的错误。
  • 这不是解决方案。即使我将嵌套级别设置为 2000,我也会看到此错误。可能我必须构建自己的字段类型。
  • @KamilP 你在设置 xdebug.max_nesting_level 后重启了 apache 吗?

标签: php rest symfony doctrine-orm doctrine


【解决方案1】:

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 模式验证器的原因。

【讨论】:

  • 我正在考虑这个问题。但在这种情况下,我无法设置多级数据。我只能设置 2 个级别。
【解决方案2】:

我建议你看看这里: https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/tree.md#tree-entity-example

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

它的模型是基于这个:https://en.wikipedia.org/wiki/Nested_set_model

【讨论】:

  • 我可以,没问题。但在此示例中,它们基于设置父级。我需要设置孩子,孩子的孩子。并且还需要与表单类型一起使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多