Laravel Amazon S3 File Upload Tutorial

  8671 views   9 months ago Laravel

AWS provides fast asset loading for web application. That's many web application serves images from AWS servers.

In this article, I will share you how you can upload file to Amazon S3 using Laravel application. We will go step by step in AWS console.

Step 1: Create S3 bucket

In the first step, we will create s3 bucket. First login to Amazon web console and login to console. In the Service Lists, select S3 option. When you click Create Bucket button, it will ask few details about bucket.

Now create I AM User and click Add Users button

Next add user name and select "Programmatic access" from access type. Then click on next.

Now select “Attach Existing Policy Directly” and choose "AmazonS3FullAccess" from permission link.

Though you can skip and click to next as it is optional.

Now view user details and then click on "Create User" button to create a new user.

You will see created user in link. You can find the "Access Key ID" and "Secret Access Key" that we will use it in .env file.

Step 2: Create Laravel application

Now we need to create fresh Laravel application using following command. We are going from scratch, So open your Terminal or CMD and run below command:

composer create-project laravel/laravel aws

Step 3: Install Amazon S3 Composer package

Now run the following command to install Amazon S3 package using composer command.

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


Step 4: Add AWS S3 Credentials

Now in your project root directory, add AWS credentials in your .env file as like below:

AWS_ACCESS_KEY_ID=AWS_ID_here
AWS_SECRET_ACCESS_KEY=AWS_KEY_here
AWS_DEFAULT_REGION=us-east-2
AWS_BUCKET=laravelcode-bucket
AWS_USE_PATH_STYLE_ENDPOINT=false

Step 5: Create routes

In this step, we will generate new two routes in web.php file. One route for generate form and another for post method So let's create both route as below.

<?php
  
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ImageController;

Route::get('image-upload', [ImageController::class, 'index' ])->name('image.index');
Route::post('image-upload', [ImageController::class, 'upload' ])->name('image.upload');

Step 6: Create ImageController

In this step, we will create ImageController and write two method index() and upload(). So one method will handle get method another one for post. So create a ImageController using command.

php artisan make:controller ImageController

Add two methods in it.

<?php
  
namespace App\Http\Controllers;
  
use Illuminate\Http\Request;
  
class ImageController extends Controller
{
     /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\View
     */
    public function index()
    {
        return view('index');
    }
    
    /**
     * handle upload file
     *
     * @return \Illuminate\Http\Response
     */
    public function post(Request $request)
    {
        $request->validate([
            'image' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048',
        ]);
    
        $image_name = time().'.'.$request->image->extension();  
     
        $path = Storage::disk('s3')->put('images', $request->image);
        $path = Storage::disk('s3')->url($path);

        // here you need to store image path in database
    
        return redirect()->back()
            ->with('success', 'Image uploaded successfully.')
            ->with('image', $path); 
    }
}

Step 7: Create Blade view

In this step, we will create a blade file for upload view. Create index.blade.php file at resources/views folder.

<!DOCTYPE html>
<html>
<head>
    <title>File upload</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
    <body>
        <div class="container">
            <div class="panel panel-primary">
              <div class="panel-heading"><h2>File upload/h2></div>
              <div class="panel-body">
                @if ($message = Session::get('success'))
                <div class="alert alert-success alert-block">
                    <button type="button" class="close" data-dismiss="alert">×</button>
                        <strong>{{ $message }}</strong>
                </div>
                <img src="{{ Session::get('image') }}">
                @endif
                @if (count($errors) > 0)
                    <div class="alert alert-danger">
                        <strong>Whoops!</strong> There were some problems with your input.
                        <ul>
                            @foreach ($errors->all() as $error)
                                <li>{{ $error }}</li>
                            @endforeach
                        </ul>
                    </div>
                @endif
                <form action="{{ route('image.upload') }}" method="post" enctype="multipart/form-data">
                    @csrf
                    <div class="row">
                        <div class="col-md-6">
                            <input type="file" name="image" class="form-control">
                        </div>
                        <div class="col-md-6">
                            <button type="submit" class="btn btn-success">Upload</button>
                        </div>
                    </div>
                </form>
              </div>
            </div>
        </div>
    </body>
</html>

Now hit the artisan command to run server.

php artisan serve

In your browser go to the http://localhost:8000/image-upload page and upload file.

Author : Harsukh Makwana
Harsukh Makwana

Hi, My name is Harsukh Makwana. i have been work with many programming language like php, python, javascript, node, react, anguler, etc.. since last 5 year. if you have any issue or want me hire then contact me on [email protected]