DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • A Guide to Using Amazon Bedrock Prompts for LLM Integration
  • The Future of Rollouts: From Big Bang to Smart and Secure Approach to Web Application Deployments
  • Automate Application Load Balancers With AWS Load Balancer Controller and Ingress
  • Running Legacy SAP Versions on AWS

Trending

  • Docker Base Images Demystified: A Practical Guide
  • The Modern Data Stack Is Overrated — Here’s What Works
  • Accelerating AI Inference With TensorRT
  • Doris: Unifying SQL Dialects for a Seamless Data Query Ecosystem
  1. DZone
  2. Software Design and Architecture
  3. Cloud Architecture
  4. How to Upload Files to Amazon S3 Using Laravel

How to Upload Files to Amazon S3 Using Laravel

It just keeps growing and growing. Check out how you can demonstrate the scalability of Amazon S3 with the Laravel framework.

By 
Alfonso Valdes user avatar
Alfonso Valdes
·
Aug. 13, 18 · Tutorial
Likes (4)
Comment
Save
Tweet
Share
83.3K Views

Join the DZone community and get the full member experience.

Join For Free

Upload Files to AWS S3 with Laravel

When maintaining a Laravel application, sometimes we need to store user files like images, PDFs, videos, etc., and the first idea that comes up is to save everything on the server. That is not a problem; in fact, it is the most common way of doing it, but at some point, our application will require to store a more significant number of files or massive files. Fortunately, AWS provides a dedicated service to upload files to Amazon S3 easily and quickly.

Simple Storage Service, Known as Amazon S3

AWS S3 is a mass storage service, virtually unlimited with really impressive advantages. We will never have to worry about adding more storage volumes to our infrastructure because the scalability of Amazon will be responsible for providing as many storage volumes as required, being transparently and practically imperceptible for the end user as well as for us.

Amazon S3 Storage has a lot of good reasons to opt for its use, but we will focus on 3:

  • 99.9% availability.
  • A permission system to access the files, completely configurable in our AWS console.
  • Allows storing files between 0 bytes and 5 gigabytes.

AWS S3 with Laravel, the Perfect Combination

Nowadays Laravel provides an easy way to integrate S3. The process to do it is really simple because Laravel has by default the configuration to use it when you want. In order to integrate it successfully, we only require our AWS credentials to access the console to create a new S3 bucket. Easy right?

Next, we will create a small application to join all these concepts and see them in action.

Getting Started

1. Create a clean installation of Laravel. In your terminal you can run this command:

laravel new laravel_s3 or composer create-project --prefer-dist laravel/laravel laravel_s3


2. Go to this link to set up an S3 bucket
2.1 Click on Create Bucket and enter a name (names of the buckets are shared among the entire Amazon S3 network, so if we create a bucket, nobody else can use that name for a new bucket).


1-laravel-file-upload-bucket


2-laravel-file-upload-bucket


3. Now we need to create a bucket policy, so we need to go to this link. To generate a proper policy you need to get the following image and select DeleteObject, GetObject, and PutObject as actions.s3 or composer create-project --prefer-dist laravel/laravel laravel_s3  

3-Laravel-amazon-s3


3.1. Click the Add Statement button and then Generate Policy.

{
  "Id": "PolicyXXXXXXXXXXX",
  "Version": "XXXXXXX",
  "Statement": [
    {
      "Sid": "StmtXXXXXXXXXX",
      "Action": [
        "s3:DeleteObject",
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::laravels3demo/images",
      "Principal": "*"
    }
  ]
}


This JSON result will be put in the Bucket Policy tab located here.

4-amazon-s3-bucket-policy-for-laravel


4. Now we will go here to get our Access Key Id and Secret Access Key to put them on our .env file.

5. In our Laravel project, we need to go to the terminal and execute the next command to install the S3 package:

composer require league/flysystem-aws-s3-v3


6. Let’s update the Laravel code

6.1 routes/web.php

<?php
Route::get('/', 'WelcomeController@index');
Route::resource('images', 'WelcomeController', ['only' => ['store', 'destroy']]);


6.2 Create a new controller and update with this code:

php artisan make:controller WelcomeController

<?php

namespace App\Http\Controllers;

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

class WelcomeController extends Controller
{
   public function index()
   {
       $url = 'https://s3.' . env('AWS_DEFAULT_REGION') . '.amazonaws.com/' . env('AWS_BUCKET') . '/';
       $images = [];
       $files = Storage::disk('s3')->files('images');
           foreach ($files as $file) {
               $images[] = [
                   'name' => str_replace('images/', '', $file),
                   'src' => $url . $file
               ];
           }

       return view('welcome', compact('images'));
   }

   public function store(Request $request)
   {
       $this->validate($request, [
           'image' => 'required|image|max:2048'
       ]);

       if ($request->hasFile('image')) {
           $file = $request->file('image');
           $name = time() . $file->getClientOriginalName();
           $filePath = 'images/' . $name;
           Storage::disk('s3')->put($filePath, file_get_contents($file));
       }

       return back()->withSuccess('Image uploaded successfully');
   }

   public function destroy($image)
   {
       Storage::disk('s3')->delete('images/' . $image);

       return back()->withSuccess('Image was deleted successfully');
   }
}


6.3 And finally will update our welcome.blade.php   view

<!doctype html>
<html lang="{{ app()->getLocale() }}">
   <head>
       <meta charset="utf-8">
       <meta http-equiv="X-UA-Compatible" content="IE=edge">
       <meta name="viewport" content="width=device-width, initial-scale=1">
       <title>Laravel S3</title>
       <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
       <link href="https://fonts.googleapis.com/css?family=Raleway:100,600" rel="stylesheet" type="text/css">
       <style>
           body, .card{
               background: #ededed;
           }
       </style>
   </head>
   <body>
       <div class="container">
           <div class="row pt-5">
               <div class="col-sm-12">
                   @if ($errors->any())
                       <div class="alert alert-danger">
                           <button type="button" class="close" data-dismiss="alert">×</button>
                           <ul>
                               @foreach ($errors->all() as $error)
                                   <li>{{ $error }}</li>
                               @endforeach
                           </ul>
                       </div>
                   @endif
                   @if (Session::has('success'))
                       <div class="alert alert-info">
                           <button type="button" class="close" data-dismiss="alert">×</button>
                           <p>{{ Session::get('success') }}</p>
                       </div>
                   @endif
               </div>
               <div class="col-sm-8">
                   @if (count($images) > 0)
                       <div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
                           <div class="carousel-inner">
                               @foreach ($images as $image)
                                   <div class="carousel-item {{ $loop->first ? 'active' : '' }}">
                                       <img class="d-block w-100" src="{{ $image['src'] }}" alt="First slide">
                                       <div class="carousel-caption">
                                           <form action="{{ url('images/' . $image['name']) }}" method="POST">
                                               {{ csrf_field() }}
                                               {{ method_field('DELETE') }}
                                               <button type="submit" class="btn btn-default">Remove</button>
                                           </form>
                                       </div>
                                   </div>
                               @endforeach
                           </div>
                           <a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
                               <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                               <span class="sr-only">Previous</span>
                           </a>
                           <a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
                               <span class="carousel-control-next-icon" aria-hidden="true"></span>
                               <span class="sr-only">Next</span>
                           </a>
                       </div>
                   @else
                       <p>Nothing found</p>
                   @endif
               </div>
               <div class="col-sm-4">
                   <div class="card border-0 text-center">
                       <form action="{{ url('/images') }}" method="POST" enctype="multipart/form-data" class="form-horizontal">
                           {{ csrf_field() }}
                           <div class="form-group">
                               <input type="file" name="image" id="image">
                           </div>
                           <div class="form-group">
                               <button type="submit" class="btn btn-primary">Upload</button>
                           </div>
                       </form>
                   </div>
               </div>
           </div>
       </div>
       <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
       <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
   </body>
</html>


7. That’s it, now our S3 and Laravel project are ready to work together.

Note: You can use Laravel Forge to create highly scalable applications on AWS.

Final thoughts

Working with S3 and Laravel is really easy and useful; on the one hand, we have all Amazon's capacity and scalability, and on the other, the solidity and practicality offered by Laravel. The combination of these two elements give us the possibility of taking our applications so far as we can imagine, even with the help of AWS Managed Services. This kind of tactic will help you to increase the performance and scalability of PHP applications, and relying on AWS to make it is the key for successful projects.

AWS Laravel Upload application

Published at DZone with permission of Alfonso Valdes. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • A Guide to Using Amazon Bedrock Prompts for LLM Integration
  • The Future of Rollouts: From Big Bang to Smart and Secure Approach to Web Application Deployments
  • Automate Application Load Balancers With AWS Load Balancer Controller and Ingress
  • Running Legacy SAP Versions on AWS

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!