Symfony2:使用VichUploaderBundle上传手动文件

时间:2015-08-04 14:36:37

标签: php symfony vichuploaderbundle

如何使用VichUploaderBundle无表格上传文件?

我在某个目录中有文件(例如web/media/tmp/temp_file.jpg

如果我试试这个:

$file = new UploadedFile($path, $filename);

$image = new Image();
$image->setImageFile($file);

$em->persist($image);
$em->flush();

我有这个错误:

  

由于未知错误,未上传文件“temp_file.jpg”。

我需要从远程网址上传文件。所以我将文件上传到tmp direcotry(使用curl),然后我一直尝试将其注入VichUploadBundle(如上所示)。

4 个答案:

答案 0 :(得分:8)

接受的答案不正确(已经?)。根据{{​​3}} 您确实可以在不使用Symfony的表单组件的情况下手动上传File

/**
 * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
 * of 'UploadedFile' is injected into this setter to trigger the  update. If this
 * bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
 * must be able to accept an instance of 'File' as the bundle will inject one here
 * during Doctrine hydration.
 *
 * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
 */
public function setImageFile(File $image = null)
{
    $this->imageFile = $image;

    if ($image) {
        // It is required that at least one field changes if you are using doctrine
        // otherwise the event listeners won't be called and the file is lost
        $this->updatedAt = new \DateTime('now');
    }
}

答案 1 :(得分:2)

您应该使用Symfony\Component\HttpFoundation\File\UploadedFile代替File

$file = new UploadedFile($filename, $filename, null, filesize($filename), false, true);

VichUploaderBundle将处理此对象。

答案 2 :(得分:1)

要结合答案并使用VichUploader解决问题,并在inject_on_load: true事件期间updatedAt更改postLoad

问题的说明
由于VictUploader托管属性不受Doctrine ORM的监视,因此您需要确保至少将ORM管理的属性之一更改为触发VichUploader用于管理prePersistpreUpdate事件文件参考。

通常通过使用文件设置器中的updatedAt DATETIME列来完成此操作,但是它可以是ORM管理的任何属性。验证提供给设置器的UploadedFile实例将确保在提交表单或手动提供updatedAt而不是postLoad事件时更改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; /** * @ORM\Entity * @Vich\Uploadable */ class Image { /** * @var \DateTime * @ORM\Column(name="updated_at", type="datetime") */ private $updatedAt; /** * @var \Symfony\Component\HttpFoundation\File\File * @Vich\UploadableField(mapping="your_mapping", fileNameProperty="image") */ private $imageFile; /** * @var string|null * @ORM\Column(name="image", type="string", length=255, nullable=true) */ private $image; public function __construct() { $this->updatedAt = new \DateTime('now'); } //... public function setImageFile(File $image = null) { $this->imageFile = $image; if ($image instanceof UploadedFile) { $this->updatedAt = new \DateTime('now'); } } }

App \ Entity \ Image

UploadedFile

然后,您可以通过实例化error对象并将null参数设置为test,将true参数设置为{{,来手动定义要在实体中使用的文件1}},它将禁用验证UPLOAD_ERR_OKis_uploaded_file() [sic]

Symfony <= 4.0

use Symfony\Component\HttpFoundation\File\UploadedFile;

$file = new UploadedFile($path, $filename, null, filesize($path), null, true);

Symfony 4.1 +

在Symfony 4.1和更高版本中,不建议使用文件大小参数。

use Symfony\Component\HttpFoundation\File\UploadedFile;

$file = new UploadedFile($path, $filename, null, null, true);

现在,您可以成功保存和/或使用手动上传的文件刷新实体了。

$image = new Image();
$image->setImageFile($file);

$em->persist($image);
$em->flush();

答案 3 :(得分:0)

简短回答:VichUploaderBundle不支持在不使用Symfony Form组件的情况下上传文件。

  

我需要从远程网址上传文件。所以我将文件上传到tmp direcotry(使用curl),然后我一直尝试将其注入VichUploadBundle(如上所示)。

在这种情况下,您无需上传,需要下载。这不是VichUploaderBundle的目的。