Symfony 5 $form->isSubmitted() 为文件上传返回 False

Symfony 5 $form->isSubmitted() Returning False for File Upload

我正在尝试通过我创建的 API 端点控制器上传文件:

/**
 * @Route("/upload", methods="POST")
 */
public function upload(Request $request)
{
    $form = $this->createForm(UserFileType::class);
    $form->handleRequest($request);

    if (!$form->isSubmitted()) {
        dd($request->files->get('file'));
    }
   ...

dd($request->files->get('file')) 按预期显示我的文件,所以我不清楚为什么 isSubmitted() 在方法接收 multipart/form-data POST 数据请求时返回 false。我正在通过 Postman 提交 POST 请求。为什么表单没有提交?

用户文件类型:

class UserFileType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('file', FileType::class, [
                'mapped' => false,
                'required' => true,
                'constraints' => [
                    new File([
                        'maxSize' => '2M',
                        'mimeTypes' => [
                            'application/pdf',
                            'application/x-pdf',
                        ],
                        'maxSizeMessage' => 'The file size must not exceed {{ limit }} {{ suffix }}.',
                        'mimeTypesMessage' => 'The file type {{ type }} is not valid',
                    ])
                ],
            ]);
    }

对于派生自 AbstractType 的表单 类,表单使用 fqcnToBlockPrefix when it's built through FormFactory.

命名

您可以通过转储来确认这一点 $form->getName()

现在,$form->handleRequest 方法在提交表单之前通过 request handler 执行大量检查。

  1. Checks the method matches that of the form
  2. Checks the name of the form is present in the request if the form has a name
  3. Checks that at least one of the form fields are filled if the form has no name

您的表单未通过请求处理程序 handleRequest 方法提交,因为请求中的字段未正确映射到您的表单名称。

您必须按以下方式在 HTTP POST 请求中映射表单名称:

[ "user_file" =>  [ "file" => <uploaded file> ] ]

这在 Postman 中可能并不直接。 因此,我建议将您的表单实现为无名表单,而不是将 getBlockPrefix 覆盖为 return 一个空字符串。


class UserFileType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        //...
    }

    public function getBlockPrefix()
    {
        return '';
    }

}