使用实体的 Symfony 4 文件上传

Symfony 4 file upload with entity

我正在开发我的模块,其中一部分是您可以将新背景添加到数据库以用于幻灯片放映。

我有一个具有 3 个属性的 SlideshowBackground 实体:

/**
 * @ORM\Id()
 * @ORM\GeneratedValue()
 * @ORM\Column(type="integer")
 */
private $id;

/**
 * @ORM\Column(type="string", length=150)
 */
private $image;

/**
 * @ORM\Column(type="string", length=100)
 */
private $imageAlt;

基本上,图像是上传文件的字符串,包括相对路径。

我有以下 SlideshowBackgroundType 作为添加幻灯片背景页的表单:

class SlideshowBackgroundType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('image', FileType::class, [
            'required' => true
        ]);
        $builder->add('imageAlt', TextType::class, ['required' => true]);
    }
}

但是,如果我提交我的表单并检查 $form->getData(),它包含以下数据:

SlideshowBackground {#419 ▼
-id: null
-image: "C:\wamp64\tmp\php5B96.tmp"
-imageAlt: "ty"
}

但是,这样我无法获取原始上传的文件名。我在控制器中使用以下代码:

$slideshowBackground = new SlideshowBackground();
$form = $this->createForm(SlideshowBackgroundType::class, $slideshowBackground);
$form->handleRequest($request);

如何在使用 SlideshowBackground 实体的同时上传未直接映射到 image 的文件?

我尝试将 image 字段修改为以下内容:

$builder->add('image', FileType::class, [
    'required' => false,
    'mapped' => false
]);

但是我从 $form->getData() 得到了相同的结果,但是 image 列为空。

此外,当我尝试使用最后一个代码提交时,我在 image 上收到以下错误:

This value should not be null.

我知道 SlideshowBackground 中的 image 属性 是必需的,它应该是,但它不起作用,因为提交时未定义 imagemapped => false。有什么办法可以解决这个问题?

我认为 OP 仍然有问题但不确定。无论如何,这有效:

class SlideshowBackgroundType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('image', FileType::class, [
            'required' => true,
            'mapped' => false, // *** NEED THIS ***
        ]);
        $builder->add('imageAlt', TextType::class, ['required' => true]);
        $builder->add('upload', SubmitType::class);
    }
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => SlideshowBackground::class,
        ]);
    }
...
class IndexController extends AbstractController
{
    /** @Route("/upload", name="upload") */
    public function upload(Request $request)
    {
        $slideshowBackground = new SlideshowBackground();
        $form = $this->createForm(SlideshowBackgroundType::class, $slideshowBackground);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {

            /** @var UploadedFile $imageFile */
            $imageFile = $form['image']->getData();
            dump($imageFile);

            // It is up to you to get the original filename per the example in the docs
            $originalFilename = pathinfo($imageFile->getClientOriginalName(), PATHINFO_FILENAME);
            // this is needed to safely include the file name as part of the URL
            //$safeFilename = transliterator_transliterate('Any-Latin; Latin-ASCII; [^A-Za-z0-9_] remove; Lower()', $originalFilename);
            //$newFilename = $safeFilename.'-'.uniqid().'.'.$brochureFile->guessExtension();

            $slideshowBackground->setImage($originalFilename); // *** NEED THIS ***
            dump($slideshowBackground);
            ...
        }

OP 编辑​​:

这个答案是正确的,但是,为了将来参考/其他人,请注意,如果在 config/packages/validator.yaml 中取消注释以下代码,这 不会 工作:

auto_mapping:
            App\Entity\: []

因此,如果此代码不起作用,请检查 auto_mapping 代码是否被注释掉。

回答者编辑:​​

我允许进行上述编辑,因为显然它解决了问题。但是,我无法重现该问题。很确定在 $form->handleRequest 和 $form->isValid 之间执行了更多代码。