How to Upload file to S3 using Laravel Filesystem

Recently I have published an article Upload Files to Amazon S3 Using AWS PHP SDK. One of our readers asked how to perform AWS S3 upload file operations with Laravel. When it comes to Laravel, we need to follow a different track compared to PHP. In this article, we study how to upload a file to S3 using a Laravel filesystem.

Laravel Filesystem provides different drivers to work with local filesystem, Amazon S3, Rackspace, etc. These drivers provide a convenient and easy way to upload files locally or on the cloud.

Amazon S3 is a popular service for storing images, files, and documents. Secondly, keeping your files on the cloud will save a lot of bandwidth for your website. It saves your hosting space plus cloud performance is scalable.

Having said that, let’s take a look at how to upload a file to S3 using the Laravel Filesystem.

Get Your AWS Security Credentials

To get started with S3, you should have an account on Amazon Web Services. Once you have it make sure to activate the S3 service.

After activating the S3 service, get your security credentials which we will need in the later part of the tutorial.

Go to credentials

S3 Driver Configuration in Laravel

As said I am going to use the Laravel Filesystem. It requires configuring the S3 driver. Head over to your editor and open the file config/filesystems.php. In this file, you can see the driver defined for S3 under ‘disks’.

config/filesystems.php

<?php

return [

    .....

    'disks' => [

        .....

        's3' => [
            'driver' => 's3',
            'key' => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
            'region' => env('AWS_DEFAULT_REGION'),
            'bucket' => env('AWS_BUCKET'),
            'url' => env('AWS_URL'),
            'endpoint' => env('AWS_ENDPOINT'),
        ],

    ],
];

In the above code Laravel uses the env() method to set the values. That means you need to define these constants in your .env file. You don’t need to define AWS_URL and AWS_ENDPOINT constants as it is not required for uploading files on the S3 bucket.

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=
AWS_BUCKET=

Add the value to each constant above. Next, open the terminal in your project root directory and run the command:

composer require league/flysystem-aws-s3-v3 ~1.0

This command will install the required library which calls the AWS API and does the cloud operations.

Upload a File to S3 in Laravel

We all set with the basic configuration. Now we can go for the actual part of file uploading. Let’s create a simple form with file input and submit button.

Add the below code in your blade file.

<form action="{{ url('ROUTE_URL') }}" method="post" enctype="multipart/form-data">
    <div class="form-group">
        <label for="exampleInputFile">File input</label>
        <input type="file" name="profile_image" id="exampleInputFile">
    </div>
    {{ csrf_field() }}
    <button type="submit" class="btn btn-default">Submit</button>
</form>

Replace the placeholder ROUTE_URL with your actual route.

Laravel gives a Storage facade which used to interact with the configured disks. In our case, the disk is S3. Add Storage facade in the controller as follows:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
...
...

After including a facade, you are able to upload files on S3. Write the code below in your method which sends the file on S3.

<?php
...
...
public function store(Request $request)
{
    if($request->hasFile('profile_image')) {

        //get filename with extension
        $filenamewithextension = $request->file('profile_image')->getClientOriginalName();

        //get filename without extension
        $filename = pathinfo($filenamewithextension, PATHINFO_FILENAME);

        //get file extension
        $extension = $request->file('profile_image')->getClientOriginalExtension();

        //filename to store
        $filenametostore = $filename.'_'.time().'.'.$extension;

        //Upload File to s3
        Storage::disk('s3')->put($filenametostore, fopen($request->file('profile_image'), 'r+'), 'public');

        //Store $filenametostore in the database
    }
}

In the above code, I am generating a unique name for the file and then upload it to S3. A user should store the filename in the database for later use. While uploading a file to S3 I passed the third parameter as ‘public’. If you don’t want to set the file as ‘public’ then skip this parameter.

The user can get the URL of uploaded file using the code:

$url = Storage::disk('s3')->url('YOUR_FILENAME_HERE');

For deleting a file from the S3 bucket, use the delete method as shown below.

Storage::disk('s3')->delete('YOUR_FILENAME_HERE');

It’s all about how to upload a file to S3 using Laravel Filesystem. I hope you got to know about the system provided by Laravel for interacting with the Amazon S3. Please share your thoughts and suggestions in the comment section below.

Related Articles

If you liked this article, then please subscribe to our YouTube Channel for video tutorials.

5 thoughts on “How to Upload file to S3 using Laravel Filesystem

  1. i have problem … my bucket name come first instead of s3-reagion/mybucket/…

    storage:: disk get the wrong url.. can you help

  2. and 1 problem again when i try to upload. i have error message :

    Missing required client configuration options: region: (string) A “region” configuration value is required for the “s3” service (e.g., “us-west-2”). A list of available public regions and endpoints can be found at http://docs.aws.amazon.com/general/latest/gr/rande.html.

    whereas the column region I have filled with valid data

  3. Thanks for your tutorial
    but i have problem with setting up laravel 5 filesystem.
    under filesystem.php says:
    ‘disks’ => [
    …………………………
    ‘s3’ => [
    ‘driver’ => ‘s3’,
    ‘key’ => env(‘key’),
    ‘secret’ => env(‘secret’),
    ‘region’ => env(“region”),
    ‘bucket’ => env(‘bucket’),
    ‘url’ => env(‘AWS_URL’),
    ],
    ],

    I am confused to fill his url column

    1. Is AWS allowed a private image to display? At the moment, I am not sure about this. I need to do some R&D on it.

Leave a Reply

Your email address will not be published. Required fields are marked *