VichUploaderBundle icon indicating copy to clipboard operation
VichUploaderBundle copied to clipboard

AWS S3 Bucket storage provider

Open SeBassFox opened this issue 4 years ago • 2 comments

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;
}
  1. 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.

SeBassFox avatar Mar 16 '20 23:03 SeBassFox

Feel free to open a PR

garak avatar Mar 17 '20 07:03 garak

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.

Nemo64 avatar May 03 '20 01:05 Nemo64