2013-02-13 1 views
4

이미지를 업로드 할 때 file 필드가있는 양식이 있습니다. 이 이미지를 Amazon S3에 업로드해야합니다. 이 단계를 단계별로 작성하여 로컬 디스크에 이미지를 업로드하기 시작했으며 현재 작동 중입니다.Symfony 2 - 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); 
     } 
    } 

그것은 완벽하다, 그것은 매력처럼 작동하고있다. symfony (2.1.7)는 file 속성의 공용 범위 때문에 소리를 지르지 만 별다른 의미는 없습니다.

이제 S3 레이어를 통합해야합니다. 그 때문에 나는 GaufretteStreamWrapper을 사용할 것입니다.

이제 가장 좋은 방법은 무엇인지 찾아내는 데 어려움을 겪고 있습니다. 엔티티의 Filesystem 서비스에 대한 액세스 권한을 얻으려면 어떻게해야합니까? 이런 식으로하는 것이 정말 깨끗한가요? Entity에서 S3의 이미지 업로드를 처리하는 것이 다소 어색하다고 느낍니다.

어떻게 하시겠습니까? 당신의 기업에 서비스를 사용

건배,

막심

+0

안녕하세요 @ maxwell2022,이 접근법을 통해이 문제를 해결하셨습니까? Gaufrette 번들 또는 Cybernox/AmazonWebServicesBundle을 사용 했습니까? 좋은 질문에 대한 Tks ... –

+0

예, 저는 Gaufrette를 사용했습니다. 대답의 코멘트를 읽고, 자세한 내용이 있습니다. – maxwell2022

답변

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

} 

희망이 맞는 예를 쓴

이 예에서 업로드 운영자 추천 것 help

+0

이 솔루션의 문제점은'Page' 엔티티를 삭제할 때 S3에서 이미지를 삭제하지 않는다는 것입니다. 'Page' 엔티티에'@ORM \ PostRemove()'가 있으면이 경우를 처리 할 수 ​​있습니다. 나는 이것에 대해 생각했지만 모든 경우 (삽입, 업데이트 및 삭제)를 가능한 최상의 방법으로 처리 할 수있는 솔루션을 찾고 싶습니다. thx – maxwell2022

+0

나는이 예제를 만들었다. 필자의 경우 pageManager 클래스는 엔티티를 유지/삭제하고 이벤트를 관리하는 서비스 계층입니다. 삭제는 다른 형태 일 수 있지만 둘 다 엔티티 관리자가 이벤트를 계속 전달합니다. –

+0

새 파일 업로드를 감지하고 이전 파일을 삭제하고 새 파일을 저장해야하므로 –

4

아마도 VichUploaderBundle을 확인해야합니다. 기본적으로 File 개체를 사용자의 entite에 삽입하고 Gaufrette와의 통합은 매우 쉽습니다.

+1

고마워. 멋지지만 내 묶음으로 처리하는 것을 선호합니다. 이해하기 쉽고 디버깅하기 쉽다. – maxwell2022