操作方法:优化Symfony表单的性能?

Mic*_*bov 21 php symfony-forms symfony doctrine-orm

我的表单是我的ajax请求的瓶颈.

    $order = $this->getDoctrine()
        ->getRepository('AcmeMyBundle:Order')
        ->find($id);
    $order = $order ? $order : new Order();

    $form = $this->createForm(new OrderType(), $order);

    $formView = $form->createView();

    return $this->render(
        'AcmeMyBundle:Ajax:order_edit.html.twig',
        array(
            'form' => $formView,
        )
    );
Run Code Online (Sandbox Code Playgroud)

为了更清晰的代码我删除了stopwatch语句.

我的OrderType有下一个字段:

    $builder
        ->add('status') // enum (string)
        ->add('paid_status') // enum (string)
        ->add('purchases_price') // int
        ->add('discount_price') // int
        ->add('delivery_price') // int
        ->add('delivery_real_price', null, array('required' => false)) // int
        ->add('buyer_name') // string
        ->add('buyer_phone') // string
        ->add('buyer_email') // string
        ->add('buyer_address') // string
        ->add('comment') // string
        ->add('manager_comment') // string
        ->add('delivery_type') // enum (string)
        ->add('delivery_track_id') // string
        ->add('payment_method') // enum (string)
        ->add('payment_id') // string
        ->add('reward') // int
        ->add('reward_status') // enum (string)
        ->add('container') // string
        ->add('partner') // Entity: User
        ->add('website', 'website') // Entity: Website
        ->add('products', 'collection', array( // Entity: Purchase
            'type' => 'purchase',
            'allow_add' => true,
            'allow_delete' => true,
            'by_reference' => false,
            'property_path' => 'purchases',
            'error_bubbling' => false,
        ));
Run Code Online (Sandbox Code Playgroud)

购买类型:

    $builder
        ->add('amount')
        ->add('price')
        ->add('code', 'variant', array(
            'property_path' => 'variantEntity',
            'data_class' => '\Acme\MyBundle\Entity\Simpla\Variant'
        ))
    ;
Run Code Online (Sandbox Code Playgroud)

此外,Purchase类型的监听器在这里并不重要.它在下面的Symfony分析器中表示为variant_retrieve,purchase_form_creating.你可以看到大约需要200ms.

在这里我把分析器的结果: SymfonyProfiler BlackFire Profiler BlackFire Profiler

正如你所看到的:$this->createForm(...)需要1011ms,$form->createView();花费2876ms并且在树枝上进行渲染也很慢:4335ms.正如blackfire profiler所说的所有交易ObjectHydrator::gatherRowData()UnitOfWork::createEntity().

createEntity()调用2223次的方法,因为有一些字段与Variant实体映射并具有表单类型Entity.但正如您从上面的代码中可以看到的那样entity,变体没有类型.我VariantType是简单的扩展text表单类型modelTransformer.为了不搞乱所有内容,您可以在docs上看到类似Type类的代码.

我的XDebug发现buildViewVariantType被称为中PurchasebuildViewtext表单类型.但在那之后从某处buildViewVariantType再次打来电话,在这种情况下,它具有entity格式类型.怎么可能?我试图在定义空数组 choices,并preferred_choices在每一个我的表单类型,但它并没有改变任何东西.我需要做些什么才能防止EntityChoiceList为我的表单加载?

gho*_*ika 0

我在实体类型上也遇到了同样的问题,我需要列出城市,有 4000 个城市,我所做的基本上是将选择注入到表单中。在控制器中,您从数据库中询问变体,在存储库调用中,将它们合并为数组,然后仅选择 id 和名称或标题,然后将其作为选项值传递到表单中。这样数据库部分就会快得多。