$ form-> createView()在Symfony2中无错误地挂起(使用失控内存)

时间:2014-04-26 06:01:16

标签: php symfony out-of-memory symfony-forms

我正在尝试在Symfony2中创建数据输入表单。如果我在控制器和模板中省略对$ form-> createView()的调用,我的页面将呈现正常。如果我将回调添加回控制器,它会挂起并最终返回没有数据的响应。

Symfony的日志将显示请求,但没有任何预期。我的apache或php错误日志中没有任何内容。

表格:

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';
    }
}

控制器:

<?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) );
    }
}

模板现在只是说'hello world'来确认控制器呈现页面。

上面的控制器会告诉我'你好世界'。如果我取消注释$ form-&gt; createView();它会挂起。如果我将render()调用切换到使用$ form-&gt; createView();它也会挂起。

为什么我的程序在这一点上失败了?什么可能会导致问题?

我在Windows / Apache开发机器上使用Symfony 2.3.12。

编辑: - &gt;添加( '打印') 绝对是问题的一部分。如果我删除它,其他一切都有效。但是,InvRecords确实定义了“打印”,就像其他值一样。来自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;
    }
}

我确认invrecord表中的相应列存在。

如果我将我的呼叫从添加('打印')更改为添加('printing_id'),我很快就会收到错误,说print_id不存在。
编辑#2: 当我在没有违规行的情况下运行页面时,Profiler会报告10mb到12mb之间的内存使用情况。使用add('printing'),它会死于我对PHP的128mb限制。

我已经安装了xdebug并获得了失败的堆栈跟踪:

[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

我希望这可以帮助我弄清楚我的代码的哪一部分触发了这个问题,但是我不明白Symfony的内部因素足以让我指向正确的方向。

任何人都可以建议哪种类型的错误或条件会导致像这样的痕迹导致内存耗尽?

1 个答案:

答案 0 :(得分:3)

add('printing')更改为add('printing','integer')可解决问题。

当所有内容都保留为默认值时,Symfony会尝试将printing视为choice字段。 printing字段是对包含大约150,000个条目的表的引用,每个条目引用另外两个表/实体。要填充<select>的值,请查询所有打印条目。然后,Symfony 单独查询两个引用实体中的每一个,每次打印。这产生了超过十万个SQL查询,从而占用了内存。

我通过将PHP内存限制提高到2048并让它在启用xdebug的情况下运行来发现这一点。希望是我会在堆栈跟踪中捕获某种循环。这个内存限制足够高,Symfony完成了它的过程并在Profiler中生成了一个报告。从那里,SQL查询的荒谬数量是显而易见的。