doulu1945 2016-06-28 15:32
浏览 54
已采纳

Symfony 3.x - 对提交的表单数据对象使用实体getId()方法返回对象(不是整数)

I am trying to create a filter form with multiple fields, and one of them is a select/drop-down for selecting from a list of Tournaments.

The idea is to make the form reusable so I'm creating a FilterType form class. The Tournament select field is created by embedding a TournamentChoiceType form class which creates an EntityType field using the Tournament entity.

The issue I'm facing is when the form is submitted and I get the submitted data. The $tournamentChoice is a Tournament object (which is OK), but $tournamentId = $tournamentChoice->getId() is returning a Tournament object too, and it should be an integer (the ID columnn).

The mess seems to happen here:

$filterForm->handleRequest($request);

because when I view/dump the raw POST request all seems normal and the filter[tournament][id] is just an integer parameter passed in, as expected.

Here's the code.

Controller:

$em = $this->getDoctrine()->getManager();
$tournamentSelected = $em->getRepository('MyBundle:Tournament')
        -> findOneById($id);
$tournamentsList = $em->getRepository('MyBundle:Tournament')
        ->findAll();

$formInputData = array();
$formInputData['tournament']['data'] = $tournamentSelected;
$formInputData['tournament']['choices'] = $tournamentsList;
formData = array();

$filterForm = $this->createForm(FilterType::class, $formData, array(
    'data' => $formInputData
));

$filterForm->handleRequest($request);

if ($filterForm->isSubmitted() && $filterForm->isValid()) {
    $formData = $filterForm->getData();

    $tournamentChoice = $formData['tournament'];
    $tournamentId = $tournamentChoice->getId();
    $dateFromChoice = $formData['date_from'];
    $dateToChoice = $formData['date_to'];

    return $this->redirectToRoute(
        'index',
        array('tournament' => $tournamentId)
    );
}

FilterType form class:

class FilterType extends AbstractType
{
    protected $data;

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => null
        ));
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $this->data = $options['data'];

        ...

        $builder
            ->add('tournament', TournamentChoiceType::class, array(
                'choices' => $this->data['tournament']['choices'],
                'data' => $this->data['tournament']['data']
            ))
        ;

        ...
    }
}

TournamentChoiceType form class:

class TournamentChoiceType extends AbstractType
{
    protected $data;
    protected $choices;

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'MyBundle\Entity\Tournament',
            'choices' => null
        ));
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $this->data = $options['data'];
        $this->choices = $options['choices'];

        $builder
            ->add('id', EntityType::class, array(
                'class' => 'MyBundle:Tournament',
                'choices' => $this->choices,
                'choice_label' => 'name',
                'label' => false,
                'data' => $this->data
            ))
        ;
    }
}

Tournament entity class:

class Tournament
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    ...

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    ...
}

Here's how var_dump($filterForm->getData()) looks like, after a submit:

array (size=4)
  'field1' => string 'text' (length=4)
  'field2' => string 'text' (length=4)
  ...
  'tournament' => 
    object(MyBundle\Entity\Tournament)[631]
      private 'id' => 
        object(MyBundle\Entity\Tournament)[522]
          private 'id' => int 11
          private 'name' => string 'tournament1' (length=11)
          private ...
          ...

and here's how var_dump($filterForm->getData()) looks like, after a second submit:

array (size=4)
  'field1' => string 'text' (length=4)
  'field2' => string 'text' (length=4)
  ...
  'tournament' => 
    object(MyBundle\Entity\Tournament)[513]
      private 'id' => 
        &object(MyBundle\Entity\Tournament)[513]
      private 'name' => string 'tournament1' (length=11)
      private ...

What's with the object's ID being an object (and not being just an interger), or referencing an object?

  • 写回答

2条回答 默认 最新

  • doukuanjing5404 2016-06-30 15:18
    关注

    The problem is caused by double data insertion. You have to refactor your code to set the data only once.

    Firstly you set it here:

    $formInputData['tournament']['data'] = $tournamentSelected;

    Secondly if there is any request, then you set it again here:

    $filterForm->handleRequest($request);

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)