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 setterFile
实例问题
验证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();