Symfony |表格 |自引用 CollectionType 字段 - 错误:内存不足 [英] Symfony | Forms | Self-referencing CollectionType field - ERROR: out of memory

查看:24
本文介绍了Symfony |表格 |自引用 CollectionType 字段 - 错误:内存不足的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先我们使用的是 Symfony 3.4.

我们在实体 Category 上有一个 自引用字段 children.所以一个类别可以有类别孩子,那些类别孩子可以有类别孩子等等......

We have a self-referencing field children on an Entity Category. So a category can have category-children and those category-children can have category-children and so on...

class Category
{
    /**
     * @ORM\Column(type="string")
     */
    private $title;

    /**
     * @ORM\OneToMany(targetEntity="AcmeBundle\Entity\Category", mappedBy="parent")
     */
    private $children;

    /**
     * @ORM\ManyToOne(targetEntity="AcmeBundle\Entity\Category", inversedBy="children")
     */
    private $parent;
}

现在我们创建了一个 API 并使用 Symfony 的表单功能来验证和创建对象数据.所以对于我们创建这个 FormType 的类别:

Now we created an API and use the form functionality of Symfony to validate and create the objects & data. So for the categories we created this FormType:

class CategoryType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title')
            ->add('children', CollectionType::class, [
                'entry_type' => CategoryType::class,
                'allow_add' => true,
                'allow_delete' => true,
                'mapped' => false,
                'by_reference' => false,
            ]);
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AcmeBundle\Entity\Category'
        ));
    }
}

这是发送到后端的API 数据数组的示例:

This is an example of the API data array that is sent to the backend:

array(2) {
    [0]=>
    array(2) {
        ["title"]=>
        string(9) "Backlight"
        ["children"]=>
        array(3) {
            [0]=>
            array(2) {
                ["title"]=>
                string(10) "Technology"
                ["children"]=>
                array(0) {
                }
            }
            [1]=>
            array(2) {
                ["title"]=>
                string(12) "Panel mount "
                ["children"]=>
                array(0) {
                }
            }
            [2]=>
            array(2) {
                ["title"]=>
                string(11) "OEM modules"
                ["children"]=>
                array(0) {
                }
            }
        }
    }
    [1]=>
    array(2) {
        ["title"]=>
        string(13) "Ball diameter"
        ["children"]=>
        array(2) {
            [0]=>
            array(2) {
                ["title"]=>
                string(18) "No pointing device"
                ["children"]=>
                array(0) {
                }
            }
            [1]=>
            array(2) {
                ["title"]=>
                string(9) "Trackball"
                ["children"]=>
                array(0) {
                }
            }
        }
    }
}

但是当我们保存并运行这段代码时,我们得到了这个错误:

But when we do the save and run this code we get this error:

[09-Aug-2018 14:41:13 Europe/Paris] PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes) in /Applications/MAMP/htdocs/acme-project/vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/OptionsResolver.php on line 865
[09-Aug-2018 14:41:13 Europe/Paris] PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 32768 bytes) in /Applications/MAMP/htdocs/acme-project/vendor/symfony/symfony/src/Symfony/Component/Debug/Exception/OutOfMemoryException.php on line 1

Sooooo,它似乎陷入了创建 FormTypes 的无限循环,因为他正在创建和无穷无尽的 children->children->children-> 集合...(OptionsResolver 是 FormType 中 configureOptions() 函数的参数)

Sooooo, it seems that it gets stuck in en infinite loop of creating FormTypes because he is creating and endless collection of children->children->children->... (The OptionsResolver is the parameter for the configureOptions() function in a FormType)

所以我的问题是,这甚至可以通过表单功能实现吗?或者我应该如何编程?或者我是否必须从 Symfony-Form 功能中删除类别的保存,并且必须编写我自己的递归保存函数?

So my question is, is this even possible with the Form functionality? Or how should I program this? Or will I have to cut out the saving of Categories from the Symfony-Form-functionality and have to write my own recursive save-function?

我见过其他人问同样的问题,但也没有得到答复:http://forum.symfony-project.org/forum/23/主题/70753.html

I've seen other people asking the same thing and also not getting an answer: http://forum.symfony-project.org/forum/23/topic/70753.html

推荐答案

我认为您应该像使用 symphony 文档中描述的那样使用表单事件 https://symfony.com/doc/current/form/dynamic_form_modification.html#dynamic-generation-for-submitted-forms在主表单上附加 PRE_SET_DATA 事件,在 title 字段上附加 POST_SUBMIT 事件.

I think you should use form events the same way as described here in symphony docs https://symfony.com/doc/current/form/dynamic_form_modification.html#dynamic-generation-for-submitted-forms attaching the PRE_SET_DATA event on the main form and the POST_SUBMIT event on the title field.

当且仅当数据位于您的模型或用户提交的数据中时,您将在表单修饰符中添加 children 字段,从而停止递归.

You will add the children field in the form modifier if and only if the data is either in your model or in the user's submitted data, thus stopping recursion.

这篇关于Symfony |表格 |自引用 CollectionType 字段 - 错误:内存不足的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆