如何处理500+项目的Symfony表单集合 [英] How to handle Symfony form collection with 500+ items

查看:182
本文介绍了如何处理500+项目的Symfony表单集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有表单集合,需要处理500多个实体实例。在我将超时时间增加到60秒之后,增加了max_input_vars的工作方式,但它很烦人。渲染表单很慢,但提交大表单就是屁股疼痛。



我正在考虑创建纯HTML表单,但还有其他一些缺点,如验证。
那么,有没有什么合适的方法可以通过symfony的形式来处理这些大数据?
$ b 控制器:

  public function ratesCardAction(){
$ bannerList = $ this-> data;

$ em = $ this-> getDoctrine() - > getManager();
$ form = $ this-> createForm(new AdvertiserRatesType($ bannerList));
if('POST'== $ this-> getRequest() - > getMethod()){
$ form-> handleRequest($ this-> getRequest());
$ advertiserCampaign = $ form-> getData();
if($ form-> isValid()){
foreach($ advertiserCampaign ['campaignsAdZones'] as $ campaignAdZone){
$ em-> persist($ campaignAdZone);
}
$ em-> flush();



返回数组
'form'=> $ form-> createView()
);



$ b class AdvertiserRatesType extends AbstractType {

public function buildForm(FormBuilderInterface $ builder,array $ options)
{
uilder - > add('campaignsAdZones','collection',array(
'type'=> new AdvertiserRatePerCountryType(),$ b $'data'=> $ this-
'empty_data'=> null,
'options'=> array(
'attr'=> array('class'=>'campaignAdZoneItem'))

))
;


$ b code $
$ b

...



和嵌入表单看起来像:

  public function buildForm(FormBuilderInterface $ builder,array 
$ {
$ builder-> add('class','entity',array(
'class'=>'AcmeCmsBundle:PublisherTypes',
' property'=>'class',
'read_only'=> true,
'disabled'=> true


- > add ('country','entity',array(
'class'=>'AcmeCmsBundle:Countries',
'property'=>'name',


- > add('text1')
- > add('text2')
;


public function setDefaultOptions(OptionsResolverInterface $ resolver)
{
$ resolver-> setDefaults(array(
'data_class'=>' Acme \CmsBundle \Entity \Rates'
));


解决方案

超过500项是一个矫枉过正;)

首先:使用纯数组而不是实体,设置'data_class'=> null setDefaultOptions 方法



第二:您不想创建500多个新的项目在一个页面上,你呢? ;)如果由于某种原因确实需要它,并且必须这样做......当前<您的code> $ advertiserCampaign = $ form-> getData(); 在您的代码将返回超过500个对象 - HEAVY。取而代之的是, $ advertiserCampaign = $ form-> getData(); 应该返回500个数据数组,然后在foreach中THEN您应该创建新对象并将数据绑定到它(例如使用数据转换)。
验证仍然可以毫无问题地进行处理 - 只需为表单类中的每个字段设置验证器即可。

第三:我希望 $ this-> rates 不是另一个对象集合 - 对吧?如果是 - 使用原始数组而不是重物。


第四:一页上有500个对象/表单?真?莫名其妙地重构?也许分页和例如每页20个表单?
如果您确实需要在一个请求中保存一个表单中的500个对象,那么我建议使用像RabbitMQ或Gearman这样的Queue处理程序将所有500个对象保存在数据库中。



我希望能有所帮助。


I have form collection which need to handle more than 500 entity instances. After I increased timeout to 60s and increased max_input_vars form work but it is annoying how slow it is. Rendering form is slow but submitting that big form is pain in the ass.

I was considering creating plain HTML form but there is some other drawback suck as validation. So, is there any proper way to handle that big set of data via symfony form ?

CONTROLLER:

public function ratesCardAction() {
    $bannerList = $this->data;

    $em = $this->getDoctrine()->getManager();
    $form = $this->createForm(new AdvertiserRatesType($bannerList));
    if ('POST' == $this->getRequest()->getMethod()) {
        $form->handleRequest($this->getRequest());
        $advertiserCampaign = $form->getData();
        if ($form->isValid()) {
            foreach ($advertiserCampaign['campaignsAdZones'] as $campaignAdZone) {
               $em->persist($campaignAdZone);
            }
            $em->flush();
        }
    }

    return array(
        'form'   => $form->createView()
    );
}



class AdvertiserRatesType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder ->add('campaignsAdZones', 'collection', array(
            'type'   => new AdvertiserRatePerCountryType(),
            'data'   => $this->rates,
            'empty_data'  => null,
            'options'  => array(
                'attr' => array('class' => 'campaignAdZoneItem')
            )
        ))
        ;
    }

}

...

and embedded form looks like:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('class', 'entity', array(
                'class' => 'AcmeCmsBundle:PublisherTypes',
                'property' => 'class',
                'read_only' => true,
                'disabled' => true
            )
        )
        ->add('country', 'entity', array(
                'class' => 'AcmeCmsBundle:Countries',
                'property' => 'name',
            )
        )
        ->add('text1')
        ->add('text2')
    ;
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'Acme\CmsBundle\Entity\Rates'
    ));
}

解决方案

Indeed using whole entities to collection with over 500 items is an overkill ;)

First: use pure arrays instead of entities, set 'data_class' => null in setDefaultOptions method

Second: You do not want to create over 500 new items on one page form, do You? ;) If it is really needed for some reason and it has to be done like that... well currently $advertiserCampaign = $form->getData(); in Your code will return over 500 objects - HEAVY. Instead of that, $advertiserCampaign = $form->getData(); should return 500 arrays of data and THEN inside foreach You should create new object and bind data to it (e.g. using datatransfomer). Validation still may be handled with no problem - just set validators for each field inside form class.

Third: I hope that $this->rates is not another collection of objects - right? In case it is - use primitive array instead of heavy objects.

Fourth: 500 objects/forms on one page? REALLY? Might it be refactored somehow? Maybe pagination and e.g. 20 forms per page? If You really, really need to save 500 objects from one form in one request, then I suggest, to use some Queue handler like RabbitMQ or Gearman to save all 500 objects in database.

I hope that helps somehow.

这篇关于如何处理500+项目的Symfony表单集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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