Php Symfony2:使用VichUploaderBundle手动上传文件

Php Symfony2:使用VichUploaderBundle手动上传文件,php,symfony,vichuploaderbundle,Php,Symfony,Vichuploaderbundle,我如何上传带有表单的文件 我在某个目录中有文件(例如web/media/tmp/temp\u file.jpg) 如果我尝试这样做: $file = new UploadedFile($path, $filename); $image = new Image(); $image->setImageFile($file); $em->persist($image); $em->flush(); 我有一个错误: 由于未知错误,未上载文件“temp_file.jpg” 我需要从

我如何上传带有表单的文件

我在某个目录中有文件(例如
web/media/tmp/temp\u file.jpg

如果我尝试这样做:

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

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

$em->persist($image);
$em->flush();
我有一个错误:

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


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

简短回答:
VichUploaderBundle
不支持在不使用Symfony表单组件的情况下上载文件

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


在这种情况下,你不需要上传,你需要下载。这不是VichUploaderBundle的本意。

公认的答案(不再)是正确的。符合 您确实可以手动上载
文件
,而无需使用Symfony的表单组件:

/**
 * 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');
    }
}

您应该使用
Symfony\Component\HttpFoundation\File\UploadedFile
而不是
File

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

VichUploaderBundle
将处理此对象。

要结合答案并解决问题,请使用VichUploader和
加载时注入:true
加载后
事件期间更改
更新的数据

对问题的解释 由于VichUploader映射属性不受ORM监控,因此您需要确保ORM管理的至少一个属性已更改,以触发VichUploader用于管理文件引用的
prePersist
preUpdate
事件。
这通常是通过在文件设置程序中使用
updatedAt
DATETIME列来完成的,但可以是ORM管理的任何属性

postLoad
event setter
File
实例问题 验证
UploadedFile
的实例是否提供给映射属性设置器方法,将确保
updatedAt
仅在表单提交期间或手动提供时更改,而不是在
postLoad
事件期间-在该事件中,VichUpload向同一映射setter方法提供
File
的实例。如果调用
$em::flush()
,则会导致视图中的
updatedAt
值发生更改,并可能会更改数据库值,前提是当
图像
对象的实例由条令加载并进行管理时

App\Entity\Image

namespace-App\Entity;
使用条令\ORM\Mapping作为ORM;
使用Symfony\Component\HttpFoundation\File\File;
使用Symfony\Component\HttpFoundation\File\UploadedFile;
使用Vich\UploaderBundle\Mapping\Annotation作为Vich;
/**
*@ORM\Entity
*@Vich\Uploadable
*/
阶级形象
{
/**
*@var\DateTime
*@ORM\Column(name=“updated_at”,type=“datetime”)
*/
私人$updatedAt;
/**
*@var\Symfony\Component\HttpFoundation\File\File
*@Vich\UploadableField(mapping=“your_mapping”,fileNameProperty=“image”)
*/
私有$imageFile;
/**
*@var字符串|空
*@ORM\Column(name=“image”,type=“string”,length=255,nullable=true)
*/
私人图像;
公共函数构造()
{
$this->updatedAt=new\DateTime('now');
}
//...
公共函数setImageFile(文件$image=null)
{
$this->imageFile=$image;
if($image instanceof UploadedFile){
$this->updatedAt=new\DateTime('now');
}
}
}


然后,您可以通过实例化一个
UploadedFile
对象并将
error
参数设置为
null
,将
test
参数设置为
true
,手动定义要在实体中使用的文件,这将禁用验证
UPLOAD\u ERR\u OK
is\u uploaded\u file()


哦,我很害怕这个。但没关系,我会想出别的办法。非常感谢你!为了完整性,最好更新您的答案,解释代码和/或最好添加指向github上相关文档的链接(如果存在,或创建PR)。这应该是可接受的答案,但正如@gp_sflover指出的,应该对其进行编辑,以进一步解释其工作原理:最后一个参数(set-mode test=true)允许在不实际上载文件的情况下使用UploadedFile,因为文件已在服务器上。
UploadedFile
如果要“上载”,对象必须将测试标志设置为true本地存储的文件,例如:将文件从本地目录迁移到VichUploader配置的上载\u目的地如何上载文件?当我设置ImageFile时,数据库将被归档,但文件从未上载到我的目标文件夹(S3上)。Thx
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();