Cómo subir archivos a Amazon S3 con Laravel

Almacenar archivos en AWS S3 con Laravel

Al mantener una aplicación PHP en Laravel, muchas veces se necesita almacenar archivos de usuario como imágenes, archivos PDF, videos, etc., y la primera idea que surge es guardar todo en el servidor. Eso no es un problema, de hecho, es la forma más común de hacerlo, pero en algún punto, tu aplicación requerirá almacenar una cantidad más grande de archivos o archivos masivos. Afortunadamente, AWS brinda un servicio dedicado para cargar archivos de manera fácil y rápida.

Simple Storage Service, conocido como Amazon S3

AWS S3 es un servicio de almacenamiento masivo, prácticamente ilimitado con ventajas realmente impresionantes. Nunca tendremos que preocuparnos por agregar más volúmenes de almacenamiento a nuestra infraestructura porque la escalabilidad de Amazon será responsable de proporcionar tantos volúmenes de almacenamiento como sea necesario, siendo transparente y prácticamente imperceptible para el usuario final y para ti como desarrollador.

Amazon S3 Storage tiene muchas buenas razones para optar por su uso, pero esta vez nos centraremos en 3:

  • 99,9% de disponibilidad
  • Un sistema de permisos para acceder a los archivos, completamente configurable en tu consola AWS.
  • Permite almacenar archivos entre 0 bytes y 5 gigabytes.

AWS S3 con Laravel, la combinación perfecta.

Hoy en día, Laravel proporciona una manera fácil de integrar Amazon S3. El proceso para hacerlo es realmente simple porque Laravel tiene por defecto la configuración para usar S3 cuando lo desees. Para integrarlo con éxito, solo necesitas tus credenciales AWS para acceder a la consola y crear un nuevo depósito S3. Fácil, ¿verdad?
A continuación, crearás una pequeña aplicación para unir todos estos conceptos y verlos en acción.

Comencemos con el proceso para subir archivos a Amazon S3 con Laravel

1. Crea una instalación limpia de Laravel, en tu terminal puedes ejecutar este comando:

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

2. Ve este link para configurar un bucket en Amazon S3:

2.2 Haz clic en Create bucket e ingresa un nombre (los nombres de los buckets se comparten entre toda la red de Amazon S3, de modo que si creamos uno, nadie más puede usar ese nombre para un bucket nuevo).

1-laravel file upload bucket
2-laravel file upload bucket

3. Ahora tienes que crear una política de bucket, para esto, ve a este link Para generar una política adecuada, debes obtener la siguiente imagen y seleccionar DeleteObject, GetObject y PutObject como acciones.

3-Laravel amazon s3

3.2 Haz clic en el botón Add Statement y luego 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": "*"
    }
  ]
}

Este resultado json se colocará en la pestaña Bucket Policy ubicada Aquí

4-amazon s3 bucket policy for laravel

4. Ahora iremos a esta dirección para obtener tu Access Key Id y Secret Access Key para colocarlo en tu .env file

5 En tu proyecto Laravel, tendrás que ir a la terminal y ejecutar el siguiente comando para instalar el paquete S3:

composer require league/flysystem-aws-s3-v3

6. Actualicemos el código de Laravel

6.2 routes/web.php

<?php

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

6.3 Crea un nuevo controlador y actualiza con este código

<!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. Eso es todo, ahora tu proyecto S3 y Laravel están listos para trabajar juntos.

Ahora ya sabes cómo almacenar archivos en Amazon S3 con Laravel

Trabajar con S3 y Laravel es realmente fácil y útil, por un lado, tienes toda la capacidad y escalabilidad de Amazon, y por el otro, la solidez y practicidad que ofrece Laravel, la combinación de estos dos elementos te da la posibilidad de llevar tus aplicaciones hasta el límite.

¡ Déjanos ayudarte con tu nueva aplicación en PHP y Laravel!

Tagged under:

Leave a Reply

Your email address will not be published.

Google Analytics Alternative