symfony 如何知道从表单中得到的这个对象的类型是什么?

How does symfony know what is the type of this object got from form?

我正在使用带有教义的 symfony 2.8(并且仍在学习,正如您将看到的那样)。

我有这个控制器,我可以在其中创建某种形式并进行渲染。 我不明白 symfony 怎么可能知道下面的 $contract 对象的类型。 然而,那些 $contract 对象最终出现在我的数据库中的合同 table 所以一定有什么东西(魔法?)我不明白发生了什么。

class MyContractsController extends BaseController
{
    public function addAction(Request $request)
    {
        $form = $this->createForm(MultiNewType::class)->handleRequest($request);

        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            foreach ($form->getData()['contracts'] as $contract) {
                $em->persist($contract);
            }
            $em->flush();
            return $this->validResponse();
        }
        return $this->renderModalFormResponse($form, array(
            'formTemplate' => 'MyBundle:Form:Contract/multiNew.html.twig'
        ));
    }

在 MultiNewType 文件下面,我没有看到任何与合同相关的内容。

class MultiNewType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('contracts', 'collection', array(
            'type' => new NewInlineType(),
            'allow_add' => true,
            'allow_delete' => true,
            'delete_empty' => true,
            'label' => false
        ));
    }

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

还有 NewInlineType,我在其中看到了合同的所有字段 table,但在任何地方都看不到合同:

class NewInlineType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('foo', 'bar', array(
                'label' => false,
                'class' => 'MyBundle:MyClass',
            ))
            ->add('format', FormatType::class, array(
                'label' => false,
            ))
            ->add('version', VersionType::class, array(
                'label' => false,
            ))
            ->add('debut', 'datePicker', array(
                'label' => false,
                'placeholder' => 'Début'
            ))
            ->add('fin', 'datePicker', array(
                'label' => false,
                'placeholder' => 'Fin'
            ));
    }

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

    public function getParent()
    {
        return 'contractEdit';
    }
}

谢谢

您的 NewInlineType 具有 parent 形式,如 getParent() 方法所示。
在这种情况下,parent 表单将从它的 getName() 方法中 return 'contractEdit'
在 parent(或可能 grand-parent)形式中,您应该找到类似以下内容的内容:

use AppBundle\Entity\Contract;
use Symfony\Component\OptionsResolver\OptionsResolver;

// ...
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => Contract::class,
    ));
}

这几乎就是它所说的;将默认 data_class 选项设置为您的合约 class 名称。