【问题标题】:Multiple Upload Symfony2多重上传 Symfony2
【发布时间】:2016-12-14 10:56:03
【问题描述】:

我是从 Symfony 开始的,但我遇到了多次上传问题。

我只能上传一个文件,我尝试修改此代码以进行多次上传。

这是我的错误:

Expected argument of type "Symfony\Component\HttpFoundation\File\UploadedFile", "array" given

这是我的代码:

ImageArticleType:

$builder
        ->add('file', 'file', array('label' => 'Choisir mes images', 'multiple'=> true))
    ;

还有我的实体ImageArticle.php

<?php

namespace AD\PlatformBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * ImageArticle
 *
 * @ORM\Table()
 * @ORM\Entity()
 * @ORM\HasLifecycleCallbacks
 */
class ImageArticle
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="url", type="string", length=255)
     */
    private $url;

    /**
     * @var string
     *
     * @ORM\Column(name="alt", type="string", length=255)
     */
    private $alt;

    /**
     * @var File
     *  
     * @Assert\File(
     *     maxSize = "1M",
     *     mimeTypes = {
     *          "image/jpeg", 
     *          "image/gif", 
     *          "image/png", 
     *          },
     *     maxSizeMessage = "La taille maximum du fichier doit etre inférieur ou égale à 1MB. Pour reduire sa taille vous pouvez utiliser le site : compressjpeg.com",
     *     mimeTypesMessage = "Seulement les fichiers .jpeg / .gif /.png sont acceptés"
     * )
     */
    private $file;

    private $tempFileName;

    public function getFile()
    {   
        return $this->file;
    }

    public function setFile(UploadedFile $file)
    {

        $this->file = $file;

        if (null !== $this->url)
        {
            $this->tempFileName = $this->url;
            $this->url=null;
            $this->alt=null;
        }
    }
    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set url
     *
     * @param string $url
     *
     * @return ImageArticle
     */
    public function setUrl($url)
    {
        $this->url = $url;

        return $this;
    }

    /**
     * Get url
     *
     * @return string
     */
    public function getUrl()
    {
        return $this->url;
    }

    /**
     * Set alt
     *
     * @param string $alt
     *
     * @return ImageArticle
     */
    public function setAlt($alt)
    {
        $this->alt = $alt;

        return $this;
    }

    /**
     * Get alt
     *
     * @return string
     */
    public function getAlt()
    {
        return $this->alt;
    }

    /**
     * @ORM\PrePersist()
     * @ORM\PreUpdate()
     */
    public function preUpload()
    {
        if (null === $this->file)
        {
            return;
        }


        //On add un extension pour le fichier.
        $this->url = $this->file->guessExtension();
        //Le alt est le nom du fichier du client.
        $this->alt=  $this->file->getClientOriginalName();

    }

    /**
     * 
     * @ORM\PostPersist()
     * @ORM\PostUpdate()
     * 
     */
    public function upload()
    {
        if(null=== $this->file)
        {
            return;
        }

        //Si ancien fichier on supprime
        if(null !== $this->tempFileName)
        {
            $oldFile = $this->getUploadRootDir().'/'.$this->id.'.'.$this->tempFileName;
            if (file_exists($oldFile))
            {
                unlink($oldFile);
            }
        }

        //On deplace
        $this->file->move
        (
            $this->getUploadRootDir(),
            $this->id.'.'.$this->url    
        );
    }

    /**
     *@ORM\PreRemove()
     */
    public function preRemoveUpload()
    {
        $this->tempFileName = $this->getUploadRootDir().'/'.$this->id.'.'.$this->url;
    }

    /**
     * 
     * @ORM\PostRemove()
     */
    public function removeUpload()
    {
        if(file_exists($this->tempFileName))
        {
            unlink($this->tempFileName);
        }
    }
    public function getUploadDir()
    {
        return 'upload/img/';
    }

    protected function getUploadRootDir()
    {
        return __DIR__.'/../../../../web/'.$this->getUploadDir();
    }

    public function __toString()
    {
        return $this->getUploadDir().$this->id.'.'.$this->getUrl();
    }

    /**
     * Set source
     *
     * @param string $source
     *
     * @return Image
     */
}

我在考虑一个简单的 foreach 循环,但它不起作用......

【问题讨论】:

  • 您的错误是告诉您您尝试传递 array 而不是 UploadedFile 类的项目。尝试从您的字段中删除 multiple 选项,这可能会呈现一个数组。
  • 感谢您的回复!如果我删除多个选项,我不能选择多个文件。
  • 是的,我知道,但是如果您仍然收到只有一个文件的错误,请尝试。如果不是你的代码是正确的,我认为你应该尝试在你的控制器中创建一个 foreach 循环,单独保存每个文件。
  • 哦,好的。是的,只有一个文件可以正常工作。在我的控制器中,我坚持/刷新我的文章。我尝试在我的文章中包含不止一张图片,因此在 ArticleType 中我将 ImageArticleType 称为 -&gt;add('imagearticle', new ImageArticleType(), array('required' =&gt; true))。我不能在我的 ImageArticle 实体中创建一个 foreach 吗?
  • 不,在你的控制器里面,看看下面的答案

标签: php symfony upload


【解决方案1】:

您的图片是保存在文章实体中还是其他(我会在收到您的答复后进行更改)?

我对您的代码做了一些小改动。我不确定所有代码,但我认为这应该可以工作

public function newArticleAction(Request $request)
{
   $article = new Article();
   $images = new ImageArticle();

   $form = $this->get('form.factory')->create(ArticleType::class, $article, $images);
   $form->handleRequest($request);

   if($form->isValid())
   {
       $article->setUser($this->getUser());
       // other article fields, if needed

       foreach($images->getFile() as $image)
       {
           $images->setAlt($image->getAlt());
           $images->setUrl($image->getUrl());
           $images->setFile($image->getFile());

           $images->preRemoveUpload();
           $images->preUpload();
           $images->upload();
       }

       $em = $this->getDoctrine()->getManager();
       $em->persist($article);
       $em->flush();

       $request->getSession()->getFlashBag()->add('notice', 'Article publié ! :)');

       return $this->redirect($this->generateUrl('va_platform_blog'));
    }

    return $this->render('ADPlatformBundle:Cars:newarticle.html.twig', [
        'form' => $form->createView(),
    ]);
}

【讨论】:

  • 我有两个实体:Article.php 和 ImageArticle.php
  • 同样的错误。 Type error: Argument 3 passed to Symfony\Component\Form\FormFactory::create() must be of the type array, object given
  • 提交期间或页面加载时?
  • 页面加载期间
  • 你能把$images 转储到$form-&gt;isValid() 吗?如果这不起作用,请评论 foreach
【解决方案2】:

类似的东西?

public function newArticleAction(Request $request)
{
   $article = new Article();
   $article->setUser($this->getUser());

   $imageArticle = new ImageArticle();

   $form = $this->get('form.factory')->create(new \AD\PlatformBundle\Form\ArticleType(), $article, $image); 
    if($form->handleRequest($request)->isValid())
    {
        foreach($imageArticle->getFile() as $imageArticle)
        {
            $imageArticle = new ImageArticle();

            $imageArticle->setAlt($imageArticle->getAlt());
            $imageArticle->setUrl($imageArticle->getUrl());
            $imageArticle->setFile($imageArticle->getFile());

            $imageArticle->preRemoveUpload();
            $imageArticle->preUpload();
            $imageArticle->upload();

        }
        $em = $this->getDoctrine()->getManager();
        $em->persist($article);
        $em->flush();

        $request->getSession()->getFlashBag()->add('notice', 'Article publié ! :)');
        return $this->redirect($this->generateUrl('va_platform_blog'));
    }
    return $this->render('ADPlatformBundle:Cars:newarticle.html.twig', array(
        'form' =>$form->createView(),
    ));
}

【讨论】:

    【解决方案3】:

    使用multiple 选项上传文件可能有点棘手。使用multiple = false 选项,您的实体类中的$file 属性将返回单个UploadedFile 实例,而multiple = true 在您调用$entity-&gt;getFile() 时返回UploadedFile 实例数组。这就是为什么您必须在表单提交时、在您的操作中手动实现上传过程,而不需要生命周期回调。像这样:

    行动:

    ....
    $image = new ImageArticle();
    
    $form = $this->createForm('YOUR_FORM', $image);
    $form->handleRequest($request);
    
    if ($form->isValid()) {
        ...
    
        foreach ($image->getFile() as $uploadedFile) {
            $image = new ImageArticle();
            $image
                // setters go here
            ;
    
            // Upload process go here
    
            $image->setFile(null);
        }
    
        $this->get('doctrine.orm.entity_manager')->flush();
    
        ....
    }
    

    这是我项目的截图:

    【讨论】:

    • 我收到了这个错误Type error: Argument 3 passed to Symfony\Component\Form\FormFactory::create() must be of the type array, object given, called in /var/www/html/QrCar/src/AD/PlatformBundle/Controller/CarsController.php on line 296
    • 这个错误告诉你$this-&gt;get('form.factory')-&gt;create()$image 参数在一个对象而不是一个数组中。您的图像是保存在article 实体还是其他实体中?
    • @Wako createForm() 方法接收('String formTypeName', Object dataObject, Array options),我认为您将对象作为第三个参数传递。阅读this
    猜你喜欢
    • 1970-01-01
    • 2015-05-10
    • 1970-01-01
    • 1970-01-01
    • 2014-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多