Symfony 2 – Лучшая практика для загрузки изображения на Amazon S3

У меня есть форма, в которой у меня есть поле для загрузки изображения. Мне нужно загрузить это изображение на 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); } } с  /** * @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 в Entity? Действительно ли это так, чтобы сделать это так? Мне немного неудобно обрабатывать загрузку изображения на S3 в Entity.

Как вы порекомендовали бы это сделать?

Ура,

Maxime

использование сервиса в вашей организации не является хорошей оценкой. Я бы рекомендовал создать обработчик формы, который выполняет проверку, сохранение и загрузку в этом примере

я написал пример, который соответствует вашим потребностям

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

Надеюсь, что это помогло

Может быть, вы должны проверить VichUploaderBundle, которые в основном вводят объект File в ваш entites, и интеграция с Gaufrette довольно проста.