dustin10 / VichUploaderBundle

A simple Symfony bundle to ease file uploads with ORM entities and ODM documents.
MIT License
1.83k stars 518 forks source link

AWS S3 Bucket storage provider #1109

Open SeBassFox opened 4 years ago

SeBassFox commented 4 years ago

Feature Request

Q A
New Feature yes
RFC yes
BC Break no

Summary

In the latest AWS SDK for PHP version 3 a stream wrapper (https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/s3-stream-wrapper.html) was added to use native php functions to save and retrieve files from a S3 Bucket. I did a quick test and with a few steps I was able to save and retrieve a file to a private bucket.

My steps:

  1. composer require aws/aws-sdk-php-symfony@^2.2 and install the recipe
  2. Set the correct region in config/packages/aws.yaml (key and secret can be set with env variables)
  3. Set the correct value in the .env file for AWS_KEY and AWS_SECRET
  4. In the config/packages/vich_uploader.yaml under mapping set the upload_destination: 's3://<bucket_name>'
  5. in the controller where you upload or download the files add with dependency injection the Aws\S3\S3Client as property, for example:
    public function __construct(S3Client $s3Client) 
    {
    $this->s3Client = $s3Client;
    }
  6. in the route method initiate the stream wrapper, for example:
    /**
    * @Route("/download/{id}", name="publication_download", methods={"GET"})
    */
    public function downloadPublications(Publication $publication, DownloadHandler $downloadHandler)
    {
    $this->s3Client->registerStreamWrapper();
    return $downloadHandler->downloadObject($publication, 'file', null, true);
    }

That's all I had to do.

So I think it should be easy to create a storage provider for this. It can extend the file_system provider and only has to init $this->s3Client->registerStreamWrapper() in the constructor. And to make it more easier it can automatically prefix the upload destination with s3://. Then the upload_destination should only be the name of the bucket (and optional path).

If this is nice to add to this bundle, then I can take some time and create the storage provider, etc. Or my example can be added to the documentation.

garak commented 4 years ago

Feel free to open a PR

Nemo64 commented 4 years ago

That's an interesting idea. But I'm not totally sure this belongs into this bundle.

As you already pointed out, stream wrappers already work not only of s3 but also the stream wrappers for flysystem and gaufrette... of ftp:// for that matter.

Also, the only reason I can think of to use the stream wrapper instead of a filesystem abstraction is that you have 1 dependency less. That's admittedly more elegant but not really worth the loss of control, the missing options, and the api call overhead since the stream wrapper has to call ListBucket so that the is_dir/mkdir calls work.