jfranc014's avatar

Move uploaded file to S3

Hi, I'm trying to upload an image to a S3 bucket. In a controller, a method called uploadPhoto() gets the uploaded file and copies to a local directory:

public function uploadPhoto(Filesystem $filesystem){
        $uploadedFile = Input::file('photo');
        $uploadedFile->move("/tmp", "test-photo.jpg");
        //...copy image to S3
    }

How is the way to move the file from the temporary folder to the S3 bucket? Does Filesystem manage this stuff? Thanks for your answers.

0 likes
9 replies
michaeldyrynda's avatar

Hey @jfranc014 what version of Laravel are you using?

Version 5 handles S3 (almost) out of the box. If you take a look at the docs for the filesystem service, with the appropriate package (league/flysystem-aws-s3-v2 ~1.0) this will be handled for you!

If you're using Version 4.x, you can still import and use flysystem, you'll just need to write the code to upload the files yourself.

1 like
lukaskorl's avatar
Level 1

In your example you could just do ...

public function uploadPhoto(Filesystem $filesystem){
    $uploadedFile = Input::file('photo');
    $s3 = Storage::disk('s3');
    $s3->put('your/s3/path/photo.jpg', file_get_contents($uploadedFile));
}
6 likes
jfranc014's avatar

@deringer. Sure i was working with S3 in L5, though i didn't remember that i could work with a local (to get the contents of the uploaded file) an a cloud filesystem (S3, to put these contents) at the same time with the Illuminate\Contracts\Filesystem\Factory. However the approach by @lukaskorl solved directly the issue. Thanks for your answers!

rainbowhat's avatar

Sorry for the hi-jack, so how do you actually get the file's URL after uploading?

Destreyf's avatar

What i did to get a signed url is the following

$bucket = 'my-bucket';
$key = "my-file.jpg";
$disk = Storage::disk('s3');
if ($disk->exists($key)) {
    $command = $disk->getDriver()->getAdapter()->getClient()->getCommand('GetObject', [
        'Bucket'                     => $bucket,
        'Key'                        => $key,
        'ResponseContentDisposition' => 'attachment;'
    ]);
    $request = $disk->getDriver()->getAdapter()->getClient()->createPresignedRequest($command, '+5 minutes');
    return (string) $request->getUri();
}

It should stand to reason that you could also use this

$bucket = 'my-bucket';
$key = "my-file.jpg";
$disk = Storage::disk('s3');
$disk->getDriver()->getAdapter()->getClient()->getObjectUrl($bucket, $key);

I got most of my information on this from the following stack overflow article: http://stackoverflow.com/questions/25323753/laravel-league-flysystem-getting-file-url-with-aws-s3

1 like
IgorSoftware's avatar

@Destreyf that dot at the end of the first line had me pulling my hair for an hour lol

$bucket = 'my-bucket'.
$key = "my-file.jpg";

should be

$bucket = 'my-bucket';
$key = "my-file.jpg";

Your last example returns regular un-presigned url for some reason but the first one works. Thanks for the help!

Anchovy's avatar

Hi

Any ideas for getting a inline image from s3?

$bucket = 'my-bucket';
$key = "my-file.jpg";
$disk = Storage::disk('s3');
if ($disk->exists($key)) {
    $command = $disk->getDriver()->getAdapter()->getClient()->getCommand('GetObject', [
        'Bucket'                     => $bucket,
        'Key'                        => $key,
        'ResponseContentDisposition' => 'attachment;'
    ]);
    $request = $disk->getDriver()->getAdapter()->getClient()->createPresignedRequest($command, '+5 minutes');
    return (string) $request->getUri();
}

I've tried changing to ResponseContentDisposition to image / inline with no luck at all and Dr. Google doesn't seem to have any idea either.

Thanks in advance.

1 like

Please or to participate in this conversation.