Symfony2:使用 VichUploaderBundle 手动上传文件
Symfony2: manual file upload with VichUploaderBundle
如何上传 VichUploaderBundle 没有表格的文件?
我在某个目录中有文件(例如web/media/tmp/temp_file.jpg
)
如果我试试这个:
$file = new UploadedFile($path, $filename);
$image = new Image();
$image->setImageFile($file);
$em->persist($image);
$em->flush();
我遇到了这个错误:
The file "temp_file.jpg" was not uploaded due to an unknown error.
我需要从远程上传文件 url。所以我将文件上传到 tmp
目录(使用 curl),然后我一直尝试将它注入 VichUploadBundle(如上所示)。
简答:VichUploaderBundle
不支持不使用 Symfony Form 组件上传文件。
I need to upload file from remote url. So I upload file to tmp direcotry (with curl) and then I keep trying to inject it to VichUploadBundle (as you can see above).
这样的话,你不需要上传,你需要下载。这不是 VichUploaderBundle
的本意。
接受的答案不正确(现在?)。根据 usage documentation
您确实可以手动上传 File
而无需使用 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 和 inject_on_load: true
在 postLoad
事件期间更改 updatedAt
的问题。
问题说明
由于 VichUploader 映射 属性 不受 Doctrine ORM 监控,您将需要确保至少更改 ORM 管理的一个属性以触发 prePersist
或 preUpdate
VichUploader 用于管理文件引用的事件。
这通常是通过在文件 setter 中使用 updatedAt
DATETIME 列来完成的,但也可以是 ORM 管理的任何 属性。
postLoad
事件 setter File
实例问题
验证 UploadedFile
的实例提供给映射的 属性 setter 方法,将确保 updatedAt
被更改 仅 在表单提交期间或手动提供时,而不是在 postLoad
事件期间 - 其中 VichUpload 将 File
的实例提供给相同的映射 setter 方法。如果在 Image
对象的实例由 Doctrine 加载并因此进行管理时调用 $em::flush()
,这将导致视图中的 updatedAt
值发生变化并可能更改数据库值。
App\Entity\Image
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');
}
}
}
然后您可以通过实例化一个 UploadedFile
对象并将 error
参数设置为 null
并将 test
参数设置为true
,禁用验证 UPLOAD_ERR_OK
和 is_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);
现在您可以成功持久化 and/or 使用手动上传的文件刷新您的实体。
$image = new Image();
$image->setImageFile($file);
$em->persist($image);
$em->flush();
如何上传 VichUploaderBundle 没有表格的文件?
我在某个目录中有文件(例如web/media/tmp/temp_file.jpg
)
如果我试试这个:
$file = new UploadedFile($path, $filename);
$image = new Image();
$image->setImageFile($file);
$em->persist($image);
$em->flush();
我遇到了这个错误:
The file "temp_file.jpg" was not uploaded due to an unknown error.
我需要从远程上传文件 url。所以我将文件上传到 tmp
目录(使用 curl),然后我一直尝试将它注入 VichUploadBundle(如上所示)。
简答:VichUploaderBundle
不支持不使用 Symfony Form 组件上传文件。
I need to upload file from remote url. So I upload file to tmp direcotry (with curl) and then I keep trying to inject it to VichUploadBundle (as you can see above).
这样的话,你不需要上传,你需要下载。这不是 VichUploaderBundle
的本意。
接受的答案不正确(现在?)。根据 usage documentation
您确实可以手动上传 File
而无需使用 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 和 inject_on_load: true
在 postLoad
事件期间更改 updatedAt
的问题。
问题说明
由于 VichUploader 映射 属性 不受 Doctrine ORM 监控,您将需要确保至少更改 ORM 管理的一个属性以触发 prePersist
或 preUpdate
VichUploader 用于管理文件引用的事件。
这通常是通过在文件 setter 中使用 updatedAt
DATETIME 列来完成的,但也可以是 ORM 管理的任何 属性。
postLoad
事件 setter File
实例问题
验证 UploadedFile
的实例提供给映射的 属性 setter 方法,将确保 updatedAt
被更改 仅 在表单提交期间或手动提供时,而不是在 postLoad
事件期间 - 其中 VichUpload 将 File
的实例提供给相同的映射 setter 方法。如果在 Image
对象的实例由 Doctrine 加载并因此进行管理时调用 $em::flush()
,这将导致视图中的 updatedAt
值发生变化并可能更改数据库值。
App\Entity\Image
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');
}
}
}
然后您可以通过实例化一个 UploadedFile
对象并将 error
参数设置为 null
并将 test
参数设置为true
,禁用验证 UPLOAD_ERR_OK
和 is_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);
现在您可以成功持久化 and/or 使用手动上传的文件刷新您的实体。
$image = new Image();
$image->setImageFile($file);
$em->persist($image);
$em->flush();