Validación de formularios en Laravel
En los formularios no nos podemos confiar de que una persona escribe correctamente lo que tiene que escribir o por intencionalidad, o por descuido por esto es que debemos hacerle una validación a nuestro formulario en este caso en Laravel.
La primera validación o chequeo con el que podemos toparnos y que debemos hacer es el de requerimiento de esta información.
Por ejemplo en el formulario de registro podría pedirnos nuestro DNI, CEDULA, CARNET DE IDENTIFICACIÓN o como se le diga en tu país.
También tenemos casos en que la información pedida en el formulario debe superar cierto numero de caracteres por ejemplo numero de teléfono celular.
¿Por que no usar Javascript?
Tenemos que tener en cuenta que utilizar Javascript para hacer la validación no es una opción confiable, siempre tendremos que realizar la validación en la parte del servidor.
Podemos utilizar Javascript para hacer la validación antes de mandar el submit del formulario para que no haga el AJAX request en vano pero tenga en cuenta que los usuarios pueden deshabilitar javascript por X motivos.
Metodo Validate
Laravel pose un método en request que se llama validate. Puedes utilizarlo para decirle si es o no requerido un input, cuantos caracteres debe tener y mas.
Creare rápido un proyecto en Laravel, y haré unas rutas. O talvez no las necesitemos después de todo Laravel puede hacer la autenticación(login, register, etc) automáticamente.
Validación en el auth generado
De esta manera puedo tener los controladores, rutas y vistas de una sola vez. Ademas veremos la validacion de uno de los formularios mas comunes en nuestros proyectos.
En ese caso solo tengo que hacer una instalación y correr el comando para crear la autenticacion.
Una vez creado el proyecto si vamos a RegisterController.php veremos la validación de el usuario antes de crearse nuestro usuario en la base de datos.
laravelexample(project name)\app\Http\Controllers\Auth\RegisterController.phpprotected function validator(array $data) { return Validator::make($data, [ 'name' => ['required', 'string', 'max:255'], 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], 'password' => ['required', 'string', 'min:8', 'confirmed'], ]); }
Esta validación es un tanto diferente a la que crearemos nosotros mismos tenga en cuenta que esta es una validación que viene por defecto en Laravel y por tanto cuando le pasemos los datos llamara a esta validación desde otro lugar.
En cambio si queremos hacer una validación como esta en nuestro proyecto para que este un tanto mas ordenado podemos crear una función con el nombre validator o validation y luego llamarla en el controlador donde mandamos la data de los input. Hagamos un ejemplo de esto.
Validación normal
Recuerdas lo que dimos en creando un formulario en Laravel?.
Pues ahora haremos la validación para ese formulario. Si sigues todos los pasos tal cual se hace en dicha entrada obtendrás ese formulario. Aquí partiré desde el formulario echo por eso no lo creare se volvería demasiado extensa la entrada.
Para que entienda lo que estamos haciendo nuestro formulario esta compuesto por los siguientes archivos
que es? | file path(ruta del archivo) o codigo |
---|---|
ruta | (routes/web) Route::get("/formulario","formulario"); |
ruta | (routes/web) Route::post(«/guardar»,»VehiculoController@guardar»);(versiones < l8) Route::post("/guardar",[VehiculoController::class, 'guardar']);(laravel 8) |
migracion | database/migrations/[date]_create_vehiculos_table.php |
vista | resources/views/formulario.blade.php |
controller | app/Http/Controllers/VehiculoController.php |
model | app/Vehiculo.php |
una vez tengamos todo funcionando deberemos hagregar nuestra validacion y respuesta a esta en la pagina.
En nuestro controlador, dentro de la función guardar agrega la validacion en su parte superior
app/Http/Controllers/VehiculoController.phpfunction guardar(Request $request){ $request->validate([ 'vehiculo' => 'required|max:3', 'modelo' => 'required', 'puertas'=> 'required|numeric', 'direccion_asistida'=> 'boolean', 'abs'=> 'boolean', 'airbags'=> 'boolean', ], $message =['required'=>'el campo :attribute es requerido', 'numeric'=> 'el campo :attribute no es numerico(Este campo necesita ser un numero)']);
En nuestro formulario deberiamos poner para manejar la variable $error la cual es la que tendra nuestros mensajes de cuando no se cumplen las reglas.
Con el siguinte codigo luego de nuestro form seria suficiente:
@if ($errors->any()) <div class="alert alert-danger"> <ul> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div> @endif
Una vez terminado nuestros cambios deberiamos obtener resultados como el siguiente:
Reglas de Validacion
accepted
El campo bajo validacion debe ser uno de los siguientes valores(‘yes’,’on’, 1, true) esta validacion se vuelve realmente util para validar terminos de servicio o campos similares.
accepted_if:campo2,valor,…
los valores deben del campo que se esta validando deben ser («yes»,»on» o true) si los valores de un segundo campo por ejemplo ‘campo2’ son un valor especifico. Por ejemplo supongamos que este es el campo de ‘terminos y servicios’ y existe otro campo ‘deseo recibir notificaciones’ este depende de si hemos aceptado los terminos y servicios
active_url
active_url valida si el campo posee un valido valor de record A o AAAA(IPv4, IPv6) con respecto a la funcion dns_get_record de PHP. El nombre de la url es extraido usando parse_url antes de ser pasado a dns_get_record.
after:date
after:date chequea si la fecha dada en el campo es mayor a la fecha dada en after:[date], la fecha sera pasada a la funcion strtotime para ser convertida a una fecha valida DateTime
'start_date' => 'required|date|after:tomorrow'
En vez de pasar un string ‘start_date’ para ser evaluado por strotime, puedes especificar otro campo para que sea comparado con la fecha.
'finish_date' => 'required|date|after:start_date'
Nuevamente vemos una validacion que puede ser muy util en reservas, por ejemplo para hotelerias.
after_or_equal:date
after_or_equal:date valida si el campo pose una fecha luego o igual a la fecha que se le esta pasando. Esta tiene mucho sentido para validar sistemas de reserva.
alpha
alpha verifica si el campo posee un valor que sea enteramente alphabetico. Por ejemplo ‘Jhon’ valores como ‘Jhon23’ no seran permitidos dandonos un error como mensaje.
alpha_dash
alpha_dash valida si el valor es alpha-numerico ademas de poder contener _ y -. Por ejemplo ‘Pepe89’ y ‘Kepler-9082’ son valores aceptados ‘kevin@23’ no lo es.
alpha_num
alpha_num evalua si el campo posee un valor alphanumerico.
array
el campo a ser validado debe ser un php array.
cuando valores adicionales son proveidos a el array, esa key en el input array debe estar presente dentro de la lista de valores dados a la regla.
Esto no esta muy claro en el ejemplo que da en la pagina oficial de laravel, ya que dice que admin no es valido pero en ese caso tampoco name ya que no esta en array rule o estoy mal? y que hay de locale?.
da el siguiente ejemplo:
use Illuminate\Support\Facades\Validator; $input = [ 'user' => [ 'name' => 'Taylor Otwell', 'username' => 'taylorotwell', 'admin' => true, ], ]; Validator::make($input, [ 'user' => 'array:username,locale', ]);
Terminando con
En general, deberias siempre especificar los array keys que son permitidos ser presentes dentro de tu array.???
Esto a mi me deja mas pregunatas que respuestas ,deberiamos probarlo.
Comming Soon
Under research, or under creation
bail
bail valida si ha habido un error, en las validaciones para el campo dado, si hay un error no sigue las validaciones de ese campo.
un ejemplo podria ser el siguiente:
$request->validate([ 'title' => 'bail|required|unique:posts|max:255', 'body' => 'required', ]);
Tambien se puede usar el metodo stopOnFirstFailure el cual informara a el validator que debe parar la validacion de los atributos una vez que una falla o error ocurra.
if ($validator->stopOnFirstFailure()->fails()) { // … }
before:date
before:data evalua el campo con respecto a la fecha dada [date], la fecha del campo debe ser una fecha anterior a la fecha dada.
before_or_equal:date
before_or_equal:date evalua que la fecha pasada en el campo sea anterior o igual a la fecha dada en [date].
between:min,max
between:min,max evalua si el valor de nuestro campo esta entre el tamaño de min y max. Esta validacion no solo se limita a numeros, tambien puede ser utilizada con string, arrays y archivos.
boolean
boolean evalua el campo dado teniendo que ser el valor de este posible de convertir a booleano, siendo asi los valores aceptados (true,false,1,0,’1′,’0′).
confirmed
The field under validation must have a matching field of {field}_confirmation. For example, if the field under validation is password, a matching password_confirmation field must be present in the input.
current_password
The field under validation must match the authenticated user’s password. You may specify an authentication guard using the rule’s first parameter:
‘password’ => ‘current_password:api’
date
date evaluara el campo si es una fecha valida(no relativa) para la funcion strtotime de PHP.
date_equals:date
date_equals:date evalua si la fecha [date] es igual a la dada en el campo.
Al igual que las anteriores Laravel usa la funcion strtotime de PHP
date_format:format
data_format:format evaluá si el valor del campo cumple con el formato dado. Deberias utilizar tambien date o date_format cuando evalúes un campo, pero no ambos. Esta validación soporta todos los formatos soportados por DateTime class.
declined
declined evaluá si el campo posee uno de los siguientes valores (‘on’,’off’,0, false). Esta evaluacion tiene sentido para cuando quieres dar de vaja algo por ejemplo no quieres tener mas notificaciones de una pagina.
En caso de no tener alguno de esos valores dara un mensaje el cual es almacenado e en $error en Laravel.
declined_if:Campo2,v2,…
Esta validación depende que el valor del campo sea (‘no’,’off’, 0, false) si Campo2 tiene valor igual a v2
En pocas palabras nuestro campo depende de otro y su valor.
different:field
different:field evalua si nuestro campo es distinto al campo pasado [field].
digits:value
el campo evaluado por digits: debe ser numerico y deve tener la misma longitud que el valor especificado en
.
digits_between:min,max
digits_between: min, max evalua si el valor del campo es numerico y esta entre min y max.
dimensions
dimensions evalua que el valor del campo sea una imagen que cumpla con las restricciones especificadas en los parametros.
Pueden ser cualquera de las siguientes (min_width, max_width, min_height, max_height, width, height, ratio.)
'avatar' => 'dimensions:min_width=100,min_height=200'
La restriccion ratio debe ser representada w/h(width/height) tambien puede ser representada con float, no se lo recomiendo.
'avatar' => 'dimensions:ratio=3/2'
Como la rega dimensions requere varios argumentos, puedes utilizar el metodo Rule::dimensions para que todo quede mas claro:
use Illuminate\Support\Facades\Validator; use Illuminate\Validation\Rule; Validator::make($data, [ 'avatar' => [ 'required', Rule::dimensions()->maxWidth(1000)->maxHeight(500)->ratio(3 / 2), ], ]);
distinct
Cuando estamos validando arrays, el campo bajo validacion no debe tener valores duplicados.
'foo.*.id' => 'distinct'
Distinct usa loose comparison, Para usar una comparasion estricta usa strict. Esto es similar a cuando usamos ==(igual) comparado a ===(equivalente)
'foo.*.id' => 'distinct:strict'
Por otro lado tenemos ignore_case esto ignora la diferencias de mayusculas.
'foo.*.id' => 'distinct:ignore_case'
email evalua si el campo tiene un valor con un formato correcto para una direccion de email. Esta regla utiliza el paquete egulias/email-validator para su validacion. Por defecto RFCValidation es aplicado, si lo deseas puedes utilizar otro tipos de validaciones o multiples validaciones
'email' => 'email:rfc,dns'
diferentes estilos de validaciones:
- rfc: RFCValidation
- strict: NoRFCWarningsValidation
- dns: DNSCheckValidation
- spoof: SpoofCheckValidation
- filter: FilterEmailValidation
regex:pattern
Es extraño no ver esta regla en la documentacion de laravel 8 pero supongo que esta debe de seguir vijente. Esta regla chequea que tu campo cumpla con la expresion regular dada. Por ejemplo:
'email' => 'regex:/^.+@.+$/i'
Under Review
this page is under review to check that all info is ok, and all examples work correctly