我有一个表格,我有一个file
字段来上传图片。我需要在Amazon S3上上传此图像。逐步构建此步骤我开始将图像上传到本地磁盘上,现在它正在运行。
上传发生在我的实体Page
内,因为建议在保存实体之前测试上传成功。我最终得到了这段代码
/**
* @ORM\Column(name="objectThumbnail", type="string", length=255, nullable=true)
*/
protected $objectThumbnail;
/**
* This is not a column in the database but it's mapping a field from the form
*
* @Assert\File(maxSize="600000000")
*/
public $file;
...
/**
* @ORM\PrePersist()
* @ORM\PreUpdate()
*/
public function preUpload()
{
if (null !== $this->file) {
// generate a unique filename
$this->objectThumbnail = $this->getGuid().'.'.$this->file->guessExtension();
}
}
/**
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function upload()
{
if (null === $this->file) {
return;
}
// if there is an error when moving the file, an exception will
// be automatically thrown by move(). This will properly prevent
// the entity from being persisted to the database on error
$this->file->move($this->getUploadRootDir(), $this->objectThumbnail);
unset($this->file);
}
/**
* @ORM\PostRemove()
*/
public function removeUpload()
{
if ($file = $this->getAbsolutePath()) {
unlink($file);
}
}
这是完美的,它的工作就像一个魅力。
Just Symfony(2.1.7)由于file
属性的公共范围而尖叫,没什么大不了的。
现在我需要集成S3层。为此,我想我将使用Gaufrette
和StreamWrapper
。
现在我很难找到最好的方法。如何访问实体中的Filesystem
服务?这样做真的很干净吗?在实体中处理S3上的图像上传感觉有点尴尬。
你会怎么建议这样做?
干杯,
马克西姆
答案 0 :(得分:5)
在您的实体中使用服务并不是一个好的实践。 我建议创建一个表单处理程序,在此示例中执行验证,持久性和上传
我写了一个符合你需求的例子
//...
//inside a creation controller action
//...
//create a new page entity
$page = new Page();
//get your page form class
$form = $this->createForm(new PageForm(), $page);
//call your form handler
$formHandler = new PageFormHandler(
$form,
$this->get('request'),
$this->get('your.gaufrette.filesystem'),
$this->get('your.page.manager')
);
//form is valid ?
if ($formHandler->process()) {
//flash message, redirection etc
}
处理程序类
namespace YourCompagnyBundle\Form\Handler;
use YourCompagnyBundle\Entity\Page;
use Symfony\Component\Form\Form;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Gaufrette\Filesystem;
class PageFormHandler
{
protected $form;
protected $request;
protected $pageManager;
protected $filesystem;
public function __construct(Form $form, Request $request, Filesystem $filesystem, $pageManager)
{
$this->form = $form;
$this->request = $request;
$this->filesystem = $filesystem;
$this->pageManager = $pageManager;
}
public function process()
{
if( $this->request->getMethod() == 'POST' )
{
$this->form->bind($this->request);
if( $this->form->isValid() )
{
$this->onSuccess($this->form->getData());
return true;
}
}
return false;
}
function onSuccess(Page $page)
{
//has uploaded file ?
if($page->getFile() instanceof UploadedFile){
//do some logic with gaufrette filesystem
//if page is already managed in database (update), delete previous file
}
//storage
$this->pageManager->save($page);
}
}
希望这有帮助
答案 1 :(得分:4)
也许你应该检查VichUploaderBundle基本上将File对象注入你的实体并与Gaufrette集成非常容易。