Symfony - 使用重复的 EntityType 优化表单

Posted

技术标签:

【中文标题】Symfony - 使用重复的 EntityType 优化表单【英文标题】:Symfony - Optimize form with repetitive EntityType 【发布时间】:2021-10-24 14:41:52 【问题描述】:

我现在正在开发的当前网站正在运行 Symfony 3.4。

我的一个实体是Contact: 我得到一个非常大的 mysql 表,其中有 ~ 14.000 行 的联系人资料:

Name Email Phone number Allocation
Brand Peter peter.brand@aol.com 49594885403 Bla blabla
.... ... ... ...

然后我有另一个实体 Event,它的自定义形式 EventForm 包括 6 个不同的插槽,引用 Contact 实体:

<?php

namespace AppBundle\Form;

/*****
** Here all my others 'use'
*****/

use AppBundle\Entity\Contact;
use AppBundle\Repository\ContactRepository;

class EventForm


    public function buildForm(FormBuilderInterface $builder, array $options)
    

        $builder
            
        // A lot of ->add(), not revelant for my issue
        
        ->add('client1', EntityType::class, [
            'class' => Client::class,
            'query_builder' => function(ClientRepository $repo) 
                return $repo->getAll();
            
        ])
        
        ->add('client2', EntityType::class, [
            'class' => Client::class,
            'query_builder' => function(ClientRepository $repo) 
                return $repo->getAll();
            
        ])
        
        // ->add('client3'), same as above
        // ->add('client4'), same as above
        // ->add('client5'), same as above
        // ->add('client6'), same as above

        ;

    

效果很好! 每个查询的处理时间为 2 秒,然后表单的总加载时间超过 10 秒。有没有办法优化我的表单以便只执行一次$repo-&gt;getAll() 查询?我也试过findAll(),但性能是一样的。

【问题讨论】:

你想做什么?添加客户?还是改变它们?您肯定应该删除查询构建部分。您正在检索所有客户 6 次!只需在 $builder 上方编写一个查询构建器,并将返回的数据用作每个客户端的变量。另外为什么你有6个?它会更多或更少吗?我认为你应该以某种方式生成这 6 个-&gt;add 东西。 我也认为展示你的控制器很重要(提交后会发生什么)。以及您所有的 ->add() 代码。因为你的加载时间都是基于这些东西。 10秒的加载时间实在是太大了。测试哪个部分花费的时间最多,并在那里进行特定的优化。您现在要问的内容太大且不清楚。它不够具体,无法按照您想要的方式修复加载时间。如果您有 10 秒的加载时间,6 个查询如何花费 2 秒? 6 * 2 = 12。不是 10... 【参考方案1】:

这样做的一种方法是创建一个属性 $clientChoices ,您可以在其中一次性存储所有 repo->getAll() 结果。为此,您必须将表单定义为服务:https://symfony.com/doc/3.4/form/form_dependencies.html

然后您将注入 EntityManager 以在构造函数中获取您想要的内容,如下所示:

<?php

namespace AppBundle\Form;

/*****
** Here all my others 'use'
*****/

use AppBundle\Entity\Contact;
use AppBundle\Repository\ContactRepository;

class EventForm

    private $clientChoices = [];

    public function __constructor(EntityManagerInterface $entityManager)
    
        $this->clientChoices = $entityManager->getRepository(Client::class)->getAll();
    

    public function buildForm(FormBuilderInterface $builder, array $options)
    

        $builder
            
        // A lot of ->add(), not revelant for my issue
        
        ->add('client1', EntityType::class, [
            'class' => Client::class,
            'choices' => $this->clientChoices,
        ])
        
        ->add('client2', EntityType::class, [
            'class' => Client::class,
            'choices' => $this->clientChoices,

            
        ])
        
        // ->add('client3'), same as above
        // ->add('client4'), same as above
        // ->add('client5'), same as above
        // ->add('client6'), same as above

        ;

    

【讨论】:

感谢您的回复。您的代码运行良好,但有一个非常奇怪的行为:性能仍然没有变化(大约 12 秒的加载时间)。但是,如果我只将'choices' =&gt; $this-&gt;clientChoices 编辑为'choices' =&gt; [] 并将存储库调用保留在构造函数中......那么加载时间为4 秒。好奇怪!

以上是关于Symfony - 使用重复的 EntityType 优化表单的主要内容,如果未能解决你的问题,请参考以下文章

使用 FOSUserBundle 自动登录 Symfony2 [重复]

无法使用 Symfony 进程运行带有参数的 Laravel Artisan 命令 [重复]

在 Doctrine2/Symfony2 中的重复条目上插入忽略

当我尝试使用 symfony 创建实体时出现 Aborted 错误消息 [重复]

如何避免 Symfony 和 locale 路由的重复内容?

SYMFONY 5 - 我尝试将 HTML 代码放在 mysql 中,但它不起作用 [重复]