How to Upload file to S3 using Laravel Filesystem

In the past, I have published an article Upload Files to Amazon S3 Using AWS PHP SDK. One of our readers asked how to perform AWS S3 file operations with Laravel. When it comes to Laravel, we need to follow a different flow compared to core PHP. Laravel has defined its own guidelines that should be implemented. In this article, we study how to upload a file to S3 using a Laravel filesystem.

Laravel Filesystem provides different drivers to work with the 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. Keeping your files on the cloud will save a lot of bandwidth for your application. It saves your hosting space and also cloud performance is scalable.

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. Laravel communicates with your AWS account via these credentials.

AWS Credentials

S3 Driver Configuration in Laravel

The Laravel filesystem requires configuring the S3 driver. Head over to the config/filesystems.php file. In this file, you can see the driver defined for S3 under the disks array.

<?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'),
            'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
        ],
 
    ],
];

Here Laravel uses the env() method to set the values for keys. That means you should define these constants in your .env file. You don’t need to add values for all these constants. Provide the details of the below constants.

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=
AWS_BUCKET=

Next, open the terminal in your project root directory and run the command:

composer require -W league/flysystem-aws-s3-v3 "^3.0"

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

Note that above command I am running on the Laravel 9.x version. For different Laravel versions, you have to run other commands.

  • Laravel 8.x : composer require --with-all-dependencies league/flysystem-aws-s3-v3 "^1.0"
  • Laravel 7.x : composer require league/flysystem-aws-s3-v3 ~1.0

Upload a File to S3 in Laravel

We are done with the basic configuration. Now we can write the actual code of file uploading. Let’s create a simple form with file input and submit button. Add the below code in your blade file say file.blade.php.

@if (session('success'))
    <strong>
        {{ session('success') }}
    </strong>
@endif

<form action="{{ url('store') }}" method="post" enctype="multipart/form-data">
    @csrf
    <p>
        Upload File <input type="file" name="profile_image" />
    </p>
    <button type="submit" name="submit">Submit</button>
</form>

I have passed the store route to the action attribute. Let’s define the required routes in the routes/web.php file.

Route::get('upload', 'FileController@index');
Route::post('store', 'FileController@store');

Create a FileController with the Artisan command:

php artisan make:controller FileController

Laravel gives a Storage facade used to interact with the configured disks(S3 in our case). Add Storage facade in the FileController 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. Define the index and store methods of the FileController as shown below.

<?php

namespace App\Http\Controllers;

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

class FileController extends Controller
{
    public function index()
    {
        return view('file');
    }

    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

            return redirect('upload')->with('success', 'File uploaded successfully.');
        }
    }
}

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.

Now run this upload route on the browser, choose a file and you will see files get uploaded on your S3 bucket.

Perform More Operations

The user can get the URL of the uploaded file by calling the url method on the disk instance:

$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');

To check if a file exists on the S3 bucket:

if (Storage::disk('s3')->exists('FILENAME')) {
    // file exists
}

Get a list of all files inside the S3 bucket:

$files = Storage::disk('s3')->files();
print_r($files);

It’s all about uploading a file to S3 using Laravel Filesystem. I hope you are now able to integrate Amazon S3 with your Laravel application. 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 *