Symfony 6 - 如何将文件上传更改为多个文件上传

Symfony 6 - How can I change file upload to multiple file uploads

提问人:Martijn van Sliedregt 提问时间:12/8/2022 最后编辑:Martijn van Sliedregt 更新时间:12/9/2022 访问量:437

问:

我正在处理一个用户能够上传文件的项目。我的代码在上传单个文件时有效,但我需要更改它,以便用户能够上传多个文件。

我想将文件作为字符串存储在我的数据库中。目前它存储为示例:“file1.png”。上传多个文件时,我希望它存储为“file1.png;文件2.png;文件3.png”。 但是,当我在表单中添加“multiple => true”时,当验证器按 submit 时,我收到一个错误,即输入需要是 String。

我最好的猜测是我需要使用数据转换器,但是在阅读文档后,我仍然不知道如何处理这个问题。?

数据转换

这是控制器(目前它需要一个文件,至于多个文件,我会使用 foreach):

\#\[Route('/new', name: 'app_blog_new', methods: \['GET', 'POST'\])\]
\#\[IsGranted('IS_AUTHENTICATED')\]
public function new(Request $request, BlogRepository $blogRepository, SluggerInterface $slugger, MailerInterface $mailer): Response
{
$blog = new Blog();
$form = $this-\>createForm(BlogType::class, $blog);
$form-\>handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $additionalImages = $form->get('additional_images')->getData();
        if ($additionalImages) {
            $originalFilename = pathinfo($additionalImages->getClientOriginalName(), PATHINFO_FILENAME);
            $safeFilename = $slugger->slug($originalFilename);
            $newFilename = $safeFilename . '-' . uniqid() . '.' . $additionalImages->guessExtension();
    
            try {
                $additionalImages->move(
                    $this->getParameter('blogimage_directory'),
                    $newFilename
                );
            } catch (FileException $e) {
                // ... handle exception if something happens during file upload
            }
    
            $blog->setAdditionalImages($newFilename);
        }
}

如果我将“multiple => true”添加到此表单中,我会在前面收到“预期字符串”错误。 这是用于将图像上传到博客的表单:


public function buildForm(FormBuilderInterface $builder, array $options): void
{
    $builder
        ->add('title')
        ->add('additional_images', FileType::class, [
            'label' => 'Additional images',
            'mapped' => false,
            'multiple' => true,
            'required' => false,
            'constraints' => [`your text`
                new File([
                    'maxSize' => '1024k',
                    'mimeTypes' => [
                        'image/*',
                    ],
                    'mimeTypesMessage' => 'Please upload a valid image',
                ])
            ],
        ]);
        $builder->get('additional_images')
            ->addModelTransformer(new CallbackTransformer(
                function ($additionalAsArray) {
                    // transform the array to a string
                    return implode('; ', $additionalAsArray);
                },
                function ($additionalAsString) {
                    // transform the string back to an array
                    return explode('; ', $additionalAsString);
                }
            ))
        ;
}

这是包含图像的博客实体类

#[ORM\Entity(repositoryClass: BlogRepository::class)]
class Blog
{
    #[ORM\Column(type: Types::TEXT, nullable: true)]
    private ?string $additional_images = null;
}

我尝试在表单中添加“multiple => true”,它有效,因为用户能够选择多个文件。但是提交后,我得到“implode():参数#1($pieces)必须是数组类型,字符串给定”

Symfony 验证

评论


答:

1赞 Martijn van Sliedregt 12/9/2022 #1

我发现我所要做的就是在表单中添加“new All”:

    ->add('additional_images', FileType::class, [
        'label' => 'Additional images',
        'mapped' => false,
        'required' => false,
        'multiple' => true,
        'constraints' => [
            new All([
                new File([
                    'maxSize' => '1024k',
                    'mimeTypes' => [
                        'image/*',
                    ],
                    'mimeTypesMessage' => 'Please upload a valid image',
                ])
            ])
        ],
    ]);

并使我的控制器与数组一起工作:

    $additionalImages = $form->get('additional_images')->getData();
    if ($additionalImages) {
        $result = array();
        foreach ($additionalImages as $image)
        {
            $originalFilename = pathinfo($image->getClientOriginalName(), PATHINFO_FILENAME);
            $safeFilename = $slugger->slug($originalFilename);
            $newFilename = $safeFilename . '-' . uniqid() . '.' . $image->guessExtension();

            try {
                $image->move(
                    $this->getParameter('blogimage_directory'),
                    $newFilename
                );
            } catch (FileException $e) {
                // ... handle exception if something happens during file upload
            }
            $result[] = $newFilename;
        }
        $blog->setAdditionalImages(implode(";", $result));

}