Almacenamiento, Streaming y Descarga

El componente Storage de Laravel nos permite de una forma muy simple  almacenar y recuperar archivos dentro de nuestra aplicación web.

Desde la versión 5.5.22, se han incluido dos nuevos métodos a este componente, que permiten retornar cualquier archivo como una descarga directa o un streaming para ser mostrado en el navegador.

Veamos un ejemplo de cómo podemos  almacenar y recuperar imágenes en Laravel 5.5.

Creando un formulario de carga de imágenes

<form action="/media" enctype="multipart/form-data" method="post">
    {{ csrf_field() }}
    <input type="file" name="file">
    <button type="submit">Upload</button>
</form>

El helper csrf_field() imprime un campo de tipo hidden que contiene un hash utilizado para proteger a la aplicación contra ataques CSRF.

Es importante incluir la propiedad enctype="multipart/form-data"en el formulario, de lo contrario el archivo no será enviado como parte de la petición.

Es necesario crear una ruta para acceder a esta vista:

Route::get('media', function () {
    return view('media');
});

Almacenando imágenes localmente

Laravel provee una serie de drivers de almacenamiento que se pueden utilizar en la aplicación. En este caso se hará uso del driver local, de esta manera todas las imágenes serán almacenadas en el directorio  storage/app.

Route::post('media', function () {
    request()->validate(['file' => 'image']);
    return request()->file->storeAs('uploads', request()->file->getClientOriginalName());
});
  • Usando request()->file accedemos al input con el nombre file del formulario que se ha creado anteriormente, esto devuelve una instancia de la clase Illuminate\Http\UploadedFile
  • El método storeAs() permite especificar un directorio y un nombre con el cual será almacenada la imagen; a su vez este método devuelve el path con el que se ha guardado la imagen, este valor puede ser almacenado en una base de datos para mantener un registro de la operación y poder acceder al archivo posteriormente.
  • El método getClientOriginalName() devuelve el nombre original del archivo, pero puede ser cambiado de ser necesario.

Accediendo a las imágenes via HTTP

En Laravel, el único directorio al que podemos acceder via HTTP es el directorio /public, pero las imágenes están siendo almacenadas en el directorio /storage, por ello, Laravel incluye un comando que permite crear un enlace simbólico entre el directorio /public/ y el directorio /storage/, para ello solo se debe ejecutar desde la terminal:

php artisan storage:link

Ahora, solo haría falta crear una ruta para acceder al archivo público:

use Illuminate\Support\Facades\Storage;

Route::get('/uploads/{file}', function ($file) {
    return Storage::response("uploads/$file");
});

El método response() devuelve un streaming que permite abrir el archivo en el navegador; si por el contrario lo que se desea es hacer una descarga directa, solo basta con reemplazar este método por download()

El método where() nos permite agregar una expresión regular que podemos usar para restringir el acceso solo a ciertos tipos de archivos.

 Route::get('/uploads/{file}', function ($file) {
    return Storage::response("uploads/$file");
})->where([
    'file' => '(.*?)\.(jpg|png|jpeg|gif)$'
]);

Material relacionado

 

Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.