Upload Files to AWS S3 using Laravel

Update: Freek Van der Herten has an updated version of this tutorial, which is better on memorey and supports larger file uploads.

Uploading to Amazon S3 can be a great way to keep your files loading quickly with their CDN, and allow you to work more on your code, rather than your filesystem.

Laravel 5’s new FileSystem makes this easy, but lacks a lot of documentation for how to actually accomplish this. First thing we need to do is tell our controller class to use the Filesystem contract and the Request class.

use Illuminate\Http\Request;
use Illuminate\Contracts\Filesystem\Filesystem;

Next, let’s setup a controller action to handle the uploaded file.

public function uploadFileToS3(Request $request)
{
$image = $request->file('image');
}

As you can see, the Request class has a specific file method for dealing with uploaded files. We assign the uploaded file to a variable, in this case $image.

Next we need to assign a file name to the uploaded file. You could leave this as the original filename, but in most cases you will want to change it to keep things consistent. Let’s change it to a timestamp, and append the file extension to it.

$imageFileName = time() . '.' . $image->getClientOriginalExtension();

Now we just need to create a new S3 Filesystem instance, define the path relative to our bucket, and upload the file. We will use the $s->put() method, and pass three perameters.

  1. Filepath relative to your bucket
  2. The contents of the file
  3. Permission of the file (optional)
$s3 = \Storage::disk('s3');
$filePath = '/support-tickets/' . $imageFileName;
$s3->put($filePath, file_get_contents($image), 'public');

That’s all there is to it. Remember to keep your API Key and Secret Key in your .env file. You don’t want those in your version control, so load them as an environment variable, like so:

's3' => [
'driver' => 's3',
'key' => env('S3_KEY'),
'secret' => env('S3_SECRET'),
'region' => env('S3_REGION'),
'bucket' => env('S3_BUCKET'),
],

Originally published at Chris Blackwell’s Domain.