Blog de programación, errores, soluciones

Chose Language:
Author: Admin/Publisher |not checked

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.php
protected 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)
migraciondatabase/migrations/[date]_create_vehiculos_table.php
vistaresources/views/formulario.blade.php
controllerapp/Http/Controllers/VehiculoController.php
modelapp/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.php
function 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)']);
Arriba puede ver la variable $message con esta puede cambiar el mensaje que da a uno mas personal o a su idioma ya que el por defecto es en ingles

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

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


Antes de laravel 5.8 laravel no utilzaba egulias/email-validator, en caso de utilizar laravel menor que 5.8 recomiendo ver el documento de la version de laravel que esta utilizando

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

Category: laravel
Something wrong? If you found an error or mistake in the content you can contact me on Twitter | @luisg2249_luis.
Last 4 post in same category