En este post voy a mostrarte cómo enviar o subir fotos con un formulario, y procesarlas para almacenarlas con Laravel.
También te voy a enseñar cómo validar las fotos, para permitir determinadas extensiones o peso.
Será un formulario que aceptará la subida de múltiples imágenes, las validará y almacenará.
Aunque es para imágenes, este ejemplo también serviría para subir otro tipo de archivos.
El formulario de la subida de imágenes queda como se ve a continuación. Es importante definir el enctype
en multipart/form-data
y poner la directiva @csrf
para el token CSRF (más información aquí)
Abajo del formulario estamos incluyendo un componente de errores, que simplemente muestra la lista de errores de validación.
<form enctype="multipart/form-data" method="post" action="{{route("agregarFotosDeArticulo")}}">
@csrf
<input accept="image/jpeg,image/png" multiple
type="file" name="fotos[]">
<button type="submit">Subir</button>
</form>
@include("errores")
Para que se puedan subir varias imágenes, se coloca el atributo multiple
en el input
. En el accept
se muestran las extensiones que permitirá (aunque esta es una validación del lado del cliente, no confíes)
El name es muy importante, sobre todo con los corchetes del final. Puedes nombrarlo como quieras, pero agrega los []
al final.
Finalmente, el action
del formulario es en la ruta agregarFotosDeArticulo
que simplemente redirige al controlador:
Route::post("articulos/fotos","ArticulosController@agregarFotos")->name("agregarFotosDeArticulo");
El componente que muestra los errores es el siguiente. Tiene algunas clases y estilos, pero eso no debe importar:
@if(!empty($errors->all()))
<div class="notification is-danger">
<h4 class="is-size-4">Por favor, valida los siguientes errores:</h4>
<ul>
@foreach ($errors->all() as $mensaje)
<li>
{{$mensaje}}
</li>
@endforeach
</ul>
</div>
@endif
Si la validación falla, los errores van a ser mostrados aquí.
Vamos a validar la petición, y para hacerla bien, vamos a crear un Request personalizado, que simplemente va a validar las imágenes.
Por favor mira más sobre las validaciones en este post, ya que aquí lo voy a resumir.
Vamos a crear el archivo app/Http/Requests/SubirFotosDeArticulosRequest.php con el siguiente contenido:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class SubirFotosDeArticulosRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/ public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/ public function rules()
{
return [
"fotos" => "required|array",
"fotos.*" => "required|image|mimes:jpeg,png|max:3000",
];
}
}
Fíjate en el método rules
, estamos regresando un arreglo que dice, en lenguaje humano:
fotos[]
) es requerido y debe ser un arreglo.Si esta validación falla, se le mostrará al usuario en el formulario en el componente de errores, además de que el método del controlador no será llamado.
Si la validación es correcta, se llamará al controlador en donde vamos a procesar los archivos subidos.
El método que se invoca es agregarFotos
, y recibe como argumento el FormRequest
que creamos anteriormente.
Para acceder a las fotos accedemos a $peticion->file("fotos")
en un foreach.
<?php
namespace App\Http\Controllers;
use App\Http\Requests\SubirFotosDeArticulosRequest;
class ArticulosController extends Controller
{
private $nombreCarpetaFotos = "fotos";
public function agregarFotos(SubirFotosDeArticulosRequest $peticion)
{
foreach ($peticion->file("fotos") as $foto) {
$fotoDeArticulo = new FotoDeArticulo;
$rutaLarga = $foto->store($this->nombreCarpetaFotos);
}
return back()
->with("mensaje", "Foto(s) agregada(s) con éxito")
->with("tipo", "success");
}
}
Para guardar la foto en el disco duro, invocamos al método llamado store
indicando el nombre de la carpeta en donde se va a almacenar.
Ese método va a devolver la ruta de la imagen recién guardada.
Opcionalmente se podrían guardar los datos de la imagen en la base de datos a través de un modelo, esto es totalmente opcional, pero si quieres llevar un registro de las fotos que se suben, deberías hacerlo.
Al final hacemos un return back()
para mostrar un mensaje de retroalimentación en el formulario, y ya quedó.
Vamos a mostrar lo aprendido aquí. Cuando los datos se envían y son correctos, se muestra un mensaje de éxito y los archivos son almacenados:
En cambio, cuando la validación falla, ya sea porque una imagen es pesada o porque algo no es una imagen, se muestran los errores:
De esta manera podemos validar no solo fotos, sino cualquier otro tipo de archivos.
Recuerda que todas las validaciones están en la documentación oficial.
Si quieres que las fotos o archivos sean opcionales, pero quieres validarlos en caso de que estén presentes, haz algo como lo siguiente:
<?php
public function rules()
{
return [
"titulo" => "required",
"contenido" => "required",
"fotos" => "sometimes|required|array",
"fotos.*" => [
new RequiredIf($this->input("fotos")),
"image",
"mimes:jpeg,png",
"max:3000",
]
];
}
Nota: mi campo en el formulario se llama fotos[]
.
Hoy te voy a presentar un creador de credenciales que acabo de programar y que…
Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…
En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…
En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…
Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…
En este artículo te voy a enseñar cómo usar un "top level await" esperando a…
Esta web usa cookies.