首页 > 解决方案 > 使用 VichUploader 和 ajax/axios 上传文件

问题描述

我正在尝试设置一个表单来使用 VichUploader 和 axios/ajax 上传文件。

我发送的表单在控制台上如下所示: chrome调试器上的表单

我已经正确设置了 vich 上传器和 GNP,因为表单在非 ajax 表单中工作。

我有一个简单的文件要上传一个实体集,如下所示:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Vich\UploaderBundle\Mapping\Annotation as Vich;

/**
 * Class Logo
 *
 * @ORM\Table(name="logos")
 * @ORM\Entity()
 * @Vich\Uploadable()
 */
class Logo
{
    /**
     * @var int
     *
     * @ORM\Column(type="integer", name="id")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $logoName;

    /**
     * NOTE: This is not a mapped field of entity metadata, just a simple property.
     *
     * @var File
     *
     * @Vich\UploadableField(mapping="logo", fileNameProperty="logoName", size="logoSize")
     */
    private $logoFile;

    /**
     * @ORM\Column(type="integer", nullable=true)
     *
     * @var integer
     */
    private $logoSize;

    /**
     * @ORM\Column(type="datetime", nullable=true)
     */
    private $updatedAt;

getter 和 setter与文档中的完全相同

我的 FormType 也很基础:

<?php

// src/Form/UserType.php
namespace App\Form;

use App\Entity\Logo;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;

use Symfony\Component\OptionsResolver\OptionsResolver;
use Vich\UploaderBundle\Form\Type\VichFileType;

class LogoType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // Remember username is email
        $builder
            ->add('logoFile', VichFileType::class, [
                'label'         => false,
                'required'      => false,
                'allow_delete'  => false,
                'download_uri'  => true,
                'download_label' => true,
                'download_link' => true,
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => Logo::class,
            'csrf_protection' => false,
        ));
    }
}

我的控制器也是如此:

    /**
     * Update a Logo for the Startup
     *
     * @Rest\Post("/logo")
     *
     * @param Request $request
     * @param UserRepository $userRepository
     *
     * @return Response
     */
    public function updateLogo(Request $request, UserRepository $userRepository): Response
    {
        $success = false;

        // Retrieve the user
        $user = $this->getUser();

//        var_dump($image);
        $startup = $user->getStartup();


        $logo = new Logo();
        $form = $this->createForm(LogoType::class, $logo);

        // Handle Submit (will only happen on POST)
        $form->submit($request->request->get('upload'));
        if ($form->isSubmitted() && $form->isValid()) {

            //Initialize EntityManager to update the user
            $entityManager = $this->getDoctrine()->getManager();

            $logo = $form->getData();
            $startup->setLogo($logo);

            try {
                $entityManager->persist($startup);
                $entityManager->flush();
            } catch (ORMException $e) {
                throw new HttpException(500, "Couldn't update your profile. Try again.");
            }

            $success = true;
        }

        $view = $this->view($success, 200);

        return $this->handleView($view);
    }

执行此操作时,它会创建一个新对象 Logo,但所有字段均为 NULL,并且没有文件上传到 AWS S3。请注意,如果我通过 logoFile 而不是 upload[logoFile] 表单将无法验证。我想通过 upload[logoFile] 是正确的做法。

不知道引擎盖下发生了什么。我错过了什么?

非常感谢。

编辑:这是我的 ajax 提交代码 - 在 React 上使用 Axios 处理:

const formData = new FormData();
    formData.append('upload[logoFile]', e.files[0]);

    axios.post('/startups/logo', formData, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    })

EDIT2:做一个 dd($request->files) 给我以下:

StartupsController.php on line 152:
FileBag^ {#73
  #parameters: array:1 [
    "upload" => array:1 [
      "logoFile" => UploadedFile^ {#63
        -test: false
        -originalName: "49138054_2423211744374313_3487352288589119488_n.jpg"
        -mimeType: "image/jpeg"
        -error: 0
        path: "/private/var/folders/wl/n382y8xs021dnbz3jhbklsnm0000gn/T"
        filename: "phpWomX0H"
        basename: "phpWomX0H"
        pathname: "/private/var/folders/wl/n382y8xs021dnbz3jhbklsnm0000gn/T/phpWomX0H"
        extension: ""
        realPath: "/private/var/folders/wl/n382y8xs021dnbz3jhbklsnm0000gn/T/phpWomX0H"
        aTime: 2019-12-11 22:02:51
        mTime: 2019-12-11 22:02:51
        cTime: 2019-12-11 22:02:51
        inode: 8664431786
        size: 106292
        perms: 0100600
        owner: 501
        group: 20
        type: "file"
        writable: true
        readable: true
        executable: false
        file: true
        dir: false
        link: false
      }
    ]
  ]
}

标签: phpsymfonysymfony4vichuploaderbundlegaufrette

解决方案


推荐阅读