Symfony 手动 $form->submit();多维数组

Symfony manually $form->submit(); with multidimensional array

我在 Symfony 5.1.7 和 $form->submit();

上苦苦挣扎了 10 个小时

我的目标是将数据转换为类似数组的 JSON API。我已经调试并找到了以下部分。

有人可以帮我看看我做错了什么吗?

为了测试它,我手动创建了一个 PHP 数组来提交它。

我在控制器中的代码

        $form = $this->createForm(AddCommentFormType::class);

        $test = [
            'content' => 'Test',
            'media' => [
                [
                    'path' => '1.png',
                ],
                [
                    'path' => '2.png',
                ],
            ],
            '_token' => '3bF4qkiUPjKNuGnbY-ySdO6B2sCLzKcS4ar7auX3Dek',
        ];

        $form->submit($test);

AddCommentFormType

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('content', TextareaType::class, [
                'constraints' => [
                    new NotBlank(),
                    new Length([
                        'max' => 10000,
                    ]),
                ],
            ])
            ->add('media', CollectionType::class, [
                'entry_type' => MediaFormType::class,
                'constraints' => [
                    new Count([
                        'min' => 1,
                        'max' => 5,
                    ]),
                ],
            ])
            ->add('_token', HiddenType::class, [
                'mapped' => false,
                'constraints' => [
                    new NotBlank(),
                ],
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'csrf_protection' => false,
        ]);
    }

MediaFormType

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('path', TextType::class, [
                'constraints' => [
                    new NotBlank(),
                ],
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Media::class,
        ]);
    }

Validator Result

children[media].data
This collection should contain 1 element or more.   
[]


children[media]
This form should not contain extra fields.  
[▼
  [▼
    "path" => "1.png"
  ]
  [▼
    "path" => "2.png"
  ]
]

如果您的类型是 AddCommentFormType,默认情况下表单期望数据位于 add_comment_form 键中,例如:

$test = [
       ‘add_comment_form’ => [
           'content' => 'Test',
        'media' => [
            [
                'path' => '1.png',
            ],
            [
                'path' => '2.png',
            ],
        ],
        '_token' => '3bF4qkiUPjKNuGnbY-ySdO6B2sCLzKcS4ar7auX3Dek',
       ]
    ];

您的表单没有默认数据,因为您使用

创建它
$form = $this->createForm(AddCommentFormType::class);

createForm 可以为默认数据附加一个参数。仅此一项不一定是问题,默认是形式的数组(或非常相似的东西,可能是空字符串而不是 null)

[
    'content' => null, 
    'media' => [], 
    '_token' => null,
]

但是,CollectionType will not allow adding or removing elements by default. Setting it's options allow_add(以及可选的 allow_remove,如果您曾经设置过默认值)会改变这一点。

所以最小的变化是:

            ->add('media', CollectionType::class, [
                'allow_add' => true,                  // <-- this is new
                'entry_type' => MediaFormType::class,
                'constraints' => [
                    new Count([
                        'min' => 1,
                        'max' => 5,
                    ]),
                ],
            ])