Click Below to subscribe

How to Upload Single Or Multiple Files to S3 Bucket in Laravel 2023

In this article, we gonna learn how to upload single/multiple files to s3 bucket in Laravel.

1. Let's create a new laravel project.

 composer create-project laravel/laravel laravel-s3-upload

2. Install the Flysystem S3 package inside the project.

Laravel 9 or 10

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

Laravel 8

composer require --with-all-dependencies league/flysystem-aws-s3-v3 "^1.0"

3. Open .env file and update these environment variables.

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false

Checkout- Generate AWS Credentials 

Checkout-  Create S3 Bucket

You may retrieve uploaded files from an Illuminate\Http\Request instance using the file method or using dynamic properties. The file method returns an instance of the Illuminate\Http\UploadedFile class which provides a variety of methods.

Ref:- https://github.com/symfony/symfony/blob/6.0/src/Symfony/Component/HttpFoundation/File/UploadedFile.php

  • getClientOriginalName()
  • getClientOriginalExtension()
  • getClientMimeType()
  • isValid() 

Also, there is another UploadedFile class that extends symfony's UploadedFile class.

Ref:- https://github.com/laravel/framework/blob/9.x/src/Illuminate/Http/UploadedFile.php

  • store(path, options)
  • storeAs(path, filename, options)
  • storePublicly(path, options)
  • storePubliclyAs(path, filename, options)

Note:- store() method internally uses storeAs() method. store() method automatically generates hash filename for our uploaded file.

// Store a file
$file->store('/', 's3');
$file->store('/', ['disk' => 's3', 'visibility' => 'public']);

$file->storeAs('/', $fileName, 's3');
$file->storeAs('/', $fileName, ['disk' => 's3', 'visibility' => 'public']);

$file->storePublicly('/', 's3'); 

$file->storePubliclyAs('/', $fileName, 's3'); 

Note:- *As methods used for setting custom file name.

    

Storage facade also provides a bunch of methods for storing and deleting files.

use Illuminate\Support\Facades\Storage;

// Store a file
Storage::disk('s3')->put($fileName, $content);
Storage::disk('s3')->put($fileName, $content, 'public');

// Delete a file
Storage::disk('s3')->delete($fileName);

// Delete multiple files
Storage::disk('s3')->delete([$fileName1, $fileName2]);

// Get file url
Storage::url($fileName);

    

Note:- By default file visibility is private so you can make it public by passing the visibility option to public

 Or you also set this at the configuration level. Open config/filesystems.php and add visibility key in the s3 array.

we can use either public or private based on requirements.

'disks' => [

        'local' => [
            'driver' => 'local',
            'root' => storage_path('app'),
            'throw' => false,
        ],

        'public' => [
            'driver' => 'local',
            'root' => storage_path('app/public'),
            'url' => env('APP_URL').'/storage',
            'visibility' => 'public',
            'throw' => false,
        ],

        '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),
            'throw' => false,
            'visibility' => 'public'
        ],

   

4. Create a controller.

php artisan make:controller UploadController

app/Http/Controllers/UploadController.php

<?php

namespace App\Http\Controllers;

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

class UploadController extends Controller
{
    public function uploadSingle(Request $request)
    {
        if ($request->hasFile('file')) {
            $file = $request->file('file');

            if ($file->isValid()) {
                $filePath = $file->store('/', ['disk' => 's3', 'visibility' => 'public']);
                $fileName = basename($filePath);

                return response()->json(['message' => 'file uploaded.']);
            }
        }
        return response()->json(['message' => 'Unable to upload file.']);
    }

    public function uploadMultiple(Request $request)
    {
        if ($request->hasFile('files')) {
            $files = $request->file('files');

            foreach ($files as $key => $file) {
                if($file->isValid()) {
                    $filePath = $file->store('/', ['disk' => 's3', 'visibility' => 'public']);
                    $fileName = basename($filePath);
                }
            }
            return response()->json(['message' => 'files uploaded.']);
        }
        return response()->json(['message' => 'Unable to upload files.']);
    }

    public function uploadSingleCustom(Request $request)
    {
        if ($request->hasFile('file')) {
            $file = $request->file('file');

            if ($file->isValid()) {
                $extension = $file->getClientOriginalExtension();
                $originalName = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
                $fileName = $originalName . '-' . uniqid() . '.' . $extension;
                Storage::disk('s3')->put($fileName, file_get_contents($file), 'public');

                return response()->json(['message' => 'file uploaded.']);
            }
        }
        return response()->json(['message' => 'Unable to upload file.']);
    }

    public function uploadMultipleCustom(Request $request)
    {
        if ($request->hasFile('files')) {
            $files = $request->file('files');

            foreach ($files as $key => $file) {
                if ($file->isValid()) {
                    $extension = $file->getClientOriginalExtension();
                    $originalName = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
                    $fileName = $originalName . '-' . uniqid() . '.' . $extension;
                    Storage::disk('s3')->put($fileName, file_get_contents($file), 'public');
                }
            }
            return response()->json(['message' => 'files uploaded.']);
        }
        return response()->json(['message' => 'Unable to upload files.']);
    }
}

 

6. Create routes

routes/api.php

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UploadController; 

Route::post('/upload-single',   [UploadController::class, 'uploadSingle']);
Route::post('/upload-multiple', [UploadController::class, 'uploadMultiple']);

Route::post('/upload-single-custom',   [UploadController::class, 'uploadSingleCustom']);
Route::post('/upload-multiple-custom', [UploadController::class, 'uploadMultipleCustom']);

Finally Open Postman or any REST API Client.

https://github.com/ultimateakash/laravel-s3-upload

If you facing any issues. don't hesitate to comment below. I will be happy to help you.

Thanks.

Leave Your Comment