Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ajck's avatar
Level 1

Syntax to copy a file from local to AWS S3?

What's the best way to copy an uploaded file from my Laravel installation (running on Heroku) to S3? I can't do a direct to S3 upload, as it's an image that I'm locally generating a thumbnail for. I also don't want to use any extra libraries etc. (sledgehammer to crack a nut etc.). File needs to go in a particular folder in my S3 bucket. Is this the only/best way? :-

Storage::disk('s3')->put('S3_folder_name/file.jpg', file_get_contents('my_local_file.jpg'));

Thanks

0 likes
7 replies
ChristophHarms's avatar

Is it the only way? No. You could, for example, use the aws-sdk directly* or just use curl (this example uses curl from the console, but doing this in PHP would be very similar).

Is it the "best" way? Depends on who you ask. Personally, I really like Laravel's Storage system, it's slick and simple and the code is easy to understand at a glance.

*Note that this would not be an extra library, since it's already in your project. Laravel's Filesystem uses the aws s3 driver from league/flysystem which in turn uses the aws-sdk-php.

martinbean's avatar

@ajck You shouldn’t be uploading to Heroku at all. It uses an “ephemeral” file system, meaning it’s not persistent and could be lost at any time (as Heroku use multiple dynos to serve your application).

Instead, you should be direct-uploading the image to S3, and then after that trigger a queued job that’ll process the image and re-upload the optimised version.

Intervention’s Image package is a good package for manipulating images. You can grab and file, process it, and re-upload it using a fluent interface:

$image = Storage::disk('s3')->get('path/to/original/file.jpg');

$image->fit(400, 300);

Storage::disk('s3')->put('path/to/new/file.jpg', $image->stream('jpg', 80));
1 like
ChristophHarms's avatar

Thanks for the clarification, @martinbean. I have never used Heroku and didn't know about their file system. I understood the question simply as "Laravel's Storage vs other means".

To put it in Genglish: Again what learned! ;)

ajck's avatar
Level 1

@martinbean Thanks, I appreciate the advice and take your point. However I did consider Heroku's ephemeral storage quite carefully, e.g. the official docs: https://devcenter.heroku.com/articles/dynos#ephemeral-filesystem . I'm only using the local storage for a fraction of a second, within the space of a single request - the likelihood of that particular dyno being lost within a request at that particular fraction of a second, is not worth bothering about I think. And the official docs do say we can use the storage :) Also, I'm not going to install more bloat into Laravel to do something I can achieve in a couple of lines of native PHP, and I wonder in the background how that package is doing what it's doing. Also seems slightly nuts to pull the image down after uploading it to S3, when at the very least the temp file uploaded from the user's browser is already on the dyno's local storage! But thanks :)

martinbean's avatar

Also seems slightly nuts to pull the image down after uploading it to S3, when at the very least the temp file uploaded from the user's browser is already on the dyno's local storage! But thanks :)

@ajck Not if the user’s uploaded a 4 MB image and then waiting around for you to process it. You want to upload the image and then return a response to the user whilst processing the image asynchronously.

Also from Heroku’s official docs:

A good rule of thumb is to avoid web requests which run longer than 500ms. If you find that your app has requests that take one, two, or more seconds to complete, then you should consider using a background job instead.

And, more relevant:

Fetching data from remote APIs, reading RSS feeds, resizing images, and uploading data to S3 are all examples of tasks that should be processed as background jobs.

Emphasis mine :)

ajck's avatar
Level 1

@martinbean OK, fair enough, those are good points. I'll follow those up as an improvement. Thanks :)

Please or to participate in this conversation.