Question

I'm trying to create a data entry form in Symfony2. My page will render just fine if I omit the call to $form->createView() in the controller and template. If I add the call back into the controller, it page hangs and eventually returns a response with no data.

Symfony's log will show the request, but with no expections. There is nothing in my apache or php error log.

The form:

namespace CoW\AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class InvCheckinForm extends AbstractType
{

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            //'csrf_protection' => false,
            //'data_class' => 'CoW\AppBundle\Entity\InvRecord',
        ));
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('bin')
            ->add('printing')
            ->add('user')
            ->add('grade')
            ->add('quantity')
            ->add('updated')
            ->add('save', 'submit');
           // ->add('dueDate', null, array('widget' => 'single_text'))
    }

    public function getName()
    {
        return 'invcheckin';
    }
}

The controller:

<?php

namespace CoW\AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
//use Symfony\Component\HttpFoundation\Response;

use CoW\AppBundle\Entity\InvRecord;
use CoW\AppBundle\Form\InvCheckinForm;

class InvController extends Controller
{

    public function checkinAction(Request $request)
    {
        $invrecord = new InvRecord();

        $form = $this->createForm(new InvCheckinForm(), $invrecord);
        //$form->createView();

        //return $this->render('CoWAppBundle:Inv:checkin.html.twig', array('invrecord' => $invrecord, 'checkinform' => $form->createView() ) );
        return $this->render('CoWAppBundle:Inv:checkin.html.twig',array('invrecord' => $invrecord) );
    }
}

The template is just says 'hello world' right now to confirm that the controller renders a page.

The above controller will show me 'hello world'. If I uncomment $form->createView(); it will hang. If I switch the render() call to the one that employs $form->createView(); it will also hang.

Why is my program failing at this point? What might cause problems here?

I'm using Symfony 2.3.12 on a Windows/Apache dev machine.

EDIT: ->add('printing') is definitely part of the problem. If I remove it, everything else works. However, InvRecords do have a 'printing' defined, just like the other values. From InvRecord.php:

class InvRecord
{
    /**
     * @ORM\ManyToOne(targetEntity="Printing")
     * @ORM\JoinColumn(name="printing_id", referencedColumnName="id")
     */
    private $printing;

    /**
     * @ORM\ManyToOne(targetEntity="Bin")
     * @ORM\JoinColumn(name="bin_id", referencedColumnName="id")
     */
    private $bin;

...


    /**
     * Set bin
     *
     * @param \CoW\AppBundle\Entity\Bin $bin
     * @return InvRecord
     */
    public function setBin(\CoW\AppBundle\Entity\Bin $bin = null)
    {
        $this->bin = $bin;

        return $this;
    }

    /**
     * Get bin
     *
     * @return \CoW\AppBundle\Entity\Bin 
     */
    public function getBin()
    {
        return $this->bin;
    }


    /**
     * Set printing
     *
     * @param \CoW\AppBundle\Entity\Printing $printing
     * @return InvRecord
     */
    public function setPrinting(\CoW\AppBundle\Entity\Printing $printing = null)
    {
        $this->printing = $printing;

        return $this;
    }

    /**
     * Get printing
     *
     * @return \CoW\AppBundle\Entity\Printing 
     */
    public function getPrinting()
    {
        return $this->printing;
    }
}

I confirmed that the corresponding column in the invrecord table exists.

If I change my call from add('printing') to add('printing_id') I get an error, quickly, saying that printing_id doesn't exist.
EDIT #2: When I run the page without the offending line, Profiler reports memory use between 10mb and 12mb. With add('printing'), it dies hitting my 128mb limit for PHP.

I've installed xdebug and gotten a stack trace of the failure:

[28-Apr-2014 14:39:28 America/Los_Angeles] PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 48 bytes) in C:\www\cow\trunk\vendor\doctrine\orm\lib\Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator.php on line 113
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP Stack trace:
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP   1. {main}() C:\www\cow\trunk\web\app_dev.php:0
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP   2. Symfony\Component\HttpKernel\Kernel->handle() C:\www\cow\trunk\web\app_dev.php:28
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP   3. Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel->handle() C:\www\cow\trunk\app\bootstrap.php.cache:2304
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP   4. Symfony\Component\HttpKernel\HttpKernel->handle() C:\www\cow\trunk\app\bootstrap.php.cache:3036
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP   5. Symfony\Component\HttpKernel\HttpKernel->handleRaw() C:\www\cow\trunk\app\bootstrap.php.cache:2897
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP   6. call_user_func_array:{C:\www\cow\trunk\app\bootstrap.php.cache:2925}() C:\www\cow\trunk\app\bootstrap.php.cache:2925
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP   7. CoW\AppBundle\Controller\InvController->checkinAction() C:\www\cow\trunk\app\bootstrap.php.cache:2925
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP   8. Symfony\Component\Form\Form->createView() C:\www\cow\trunk\src\CoW\AppBundle\Controller\InvController.php:22
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP   9. Symfony\Component\Form\Form->createView() C:\www\cow\trunk\vendor\symfony\symfony\src\Symfony\Component\Form\Form.php:1022
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP  10. Symfony\Component\Form\Extension\DataCollector\Proxy\ResolvedTypeDataCollectorProxy->buildView() C:\www\cow\trunk\vendor\symfony\symfony\src\Symfony\Component\Form\Form.php:1019
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP  11. Symfony\Component\Form\ResolvedFormType->buildView() C:\www\cow\trunk\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\DataCollector\Proxy\ResolvedTypeDataCollectorProxy.php:111
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP  12. Symfony\Component\Form\Extension\DataCollector\Proxy\ResolvedTypeDataCollectorProxy->buildView() C:\www\cow\trunk\vendor\symfony\symfony\src\Symfony\Component\Form\ResolvedFormType.php:160
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP  13. Symfony\Component\Form\ResolvedFormType->buildView() C:\www\cow\trunk\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\DataCollector\Proxy\ResolvedTypeDataCollectorProxy.php:111
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP  14. Symfony\Component\Form\Extension\Core\Type\ChoiceType->buildView() C:\www\cow\trunk\vendor\symfony\symfony\src\Symfony\Component\Form\ResolvedFormType.php:163
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP  15. Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList->getPreferredViews() C:\www\cow\trunk\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\Core\Type\ChoiceType.php:101
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP  16. Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList->load() C:\www\cow\trunk\vendor\symfony\symfony\src\Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList.php:173
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP  17. Doctrine\ORM\EntityRepository->findAll() C:\www\cow\trunk\vendor\symfony\symfony\src\Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList.php:429
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP  18. Doctrine\ORM\EntityRepository->findBy() C:\www\cow\trunk\vendor\doctrine\orm\lib\Doctrine\ORM\EntityRepository.php:164
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP  19. Doctrine\ORM\Persisters\BasicEntityPersister->loadAll() C:\www\cow\trunk\vendor\doctrine\orm\lib\Doctrine\ORM\EntityRepository.php:181
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP  20. Doctrine\ORM\Internal\Hydration\AbstractHydrator->hydrateAll() C:\www\cow\trunk\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\BasicEntityPersister.php:934
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP  21. Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator->hydrateAllData() C:\www\cow\trunk\vendor\doctrine\orm\lib\Doctrine\ORM\Internal\Hydration\AbstractHydrator.php:140
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP  22. Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator->hydrateRowData() C:\www\cow\trunk\vendor\doctrine\orm\lib\Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator.php:48
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP  23. Doctrine\ORM\UnitOfWork->createEntity() C:\www\cow\trunk\vendor\doctrine\orm\lib\Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator.php:132
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP  24. Doctrine\ORM\Persisters\BasicEntityPersister->loadOneToOneEntity() C:\www\cow\trunk\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php:2656
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP  25. Doctrine\ORM\Persisters\BasicEntityPersister->load() C:\www\cow\trunk\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\BasicEntityPersister.php:800
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP  26. Doctrine\ORM\Internal\Hydration\AbstractHydrator->hydrateAll() C:\www\cow\trunk\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\BasicEntityPersister.php:756
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP  27. Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator->hydrateAllData() C:\www\cow\trunk\vendor\doctrine\orm\lib\Doctrine\ORM\Internal\Hydration\AbstractHydrator.php:140
[28-Apr-2014 14:39:28 America/Los_Angeles] PHP  28. Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator->hydrateRowData() C:\www\cow\trunk\vendor\doctrine\orm\lib\Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator.php:48

I was hoping this would help me figure out what part of my code is triggering the problem, but I don't understand Symfony internals enough for this trace to point me in the right direction.

Can anyone suggest what type of mistakes or conditions would cause runaway memory consumption with a trace like this?

Was it helpful?

Solution

Changing add('printing') to add('printing','integer') solves the problem.

When everything was left at defaults Symfony tried to treat printing as a choice field. The printing field is a reference to a table with roughly 150,000 entries, each of which references two other tables/entities. To populate values for the <select>, all printing entries were queried. Then, Symfony individually queried for each of the two referenced entities, for every single printing. This generated over a hundred thousand SQL queries, thus eating up memory.

I discovered this by cranking up the PHP memory limit to 2048, and letting it run with xdebug enabled. The hope was the I would catch some kind of telling loop in the stack trace. This memory limit was high enough that Symfony completed its process and generated a report in Profiler. From there, the absurd quantity of SQL queries was obvious.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top