Symfony的2 - 最佳实践上载在Amazon S3图像 [英] Symfony 2 - Best practice to upload an image on Amazon S3

查看:125
本文介绍了Symfony的2 - 最佳实践上载在Amazon S3图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个形式,我有一个文件字段来上传图片。我需要上传到Amazon S3的这一形象。建立这一步一步,我开始上传本地磁盘上的形象和它现在的工作。

I have a form in which I have a file field to upload an image. I need to upload this image on Amazon S3. Building this step by step I started to upload the image on the local disk and it's now working.

上传发生我的实体内,因为它是建议测试上传的成功之前保存的实体。我结束了这个块的code

The upload is occurring inside my entity Page as it's recommended to test the success of the upload before to save the entity. I ended up with this chunk of code

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

这是完美的,它像一个魅力的工作。 只是Symfony的(2.1.7)的因公范围尖叫文件属性,没有重大。

That's perfect, it's working like a charm. Just Symfony (2.1.7) screaming because of the public scope of the file attribute, nothing major.

现在我需要的S3层集成。为此,我想我会使用 Gaufrette StreamWrapper

Now I need to integrate the S3 layer. For that I think I'll be using Gaufrette and StreamWrapper.

现在我在努力寻找什么是做到这一点的最好办法。如何获得访问文件系统服务于实体?是不是真的干净到像这样做?感觉有点别扭给我来处理实体的S3图像的上传。

Now I'm struggling to find what is the best way to do it. How do I get access to the Filesystem service in the Entity? Is it really clean to do it like this? It feels a bit awkward to me to process the upload of the image on S3 in the Entity.

你怎么会推荐这样做呢?

How would you recommend to do it ?

干杯,

马克西姆

推荐答案

在实体使用的服务是不是一个很好的实践。 我会推荐给创建一个表单处理程序进行验证,持久性和上传在这个例子中

using service in your entity is not a good pratice. I would recommand to create a form handler that performs validation, persistance and upload in this example

我写了一个适合您的需求的一个例子

i wrote an example that fits your needs

//...
//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
}

的处理程序类

The handler class

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);
    }

}

希望这有助于

Hope this helped

这篇关于Symfony的2 - 最佳实践上载在Amazon S3图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆