Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Curso de PHP con Laravel

Curso de PHP con Laravel

Héctor Benitez

Héctor Benitez

Validaciones

18/25
Recursos

Es muy importante validar siempre la información que los usuarios ingresan en el sistema. En la mayoría de los casos tendrás usuarios bien intencionados que sólo busquen hacer uso del sistema, pero puede ocurrir que haya algún atacante que quiera obtener información que no le pertenece.

Cuando por ejemplo se hace submit a un form vacío, no vamos a querer que el usuario final vea los errores como son lanzados sino manejarlos de alguna manera, así que los validamos con ayuda de Laravel.
Laravel incluye todos los errores de validación que podamos encontrar dentro de un objeto especial llamado errors el cual podemos usar en nuestro template.

  • Se utiliza la línea vertical | para agregar más validaciones.
  • Si un usuario se equivoca al llenar los campos de formulario y al intentarlo de nuevo debe ingresarlos todos otra vez, eso significará una mala experiencia de usuario y creará frustración. Por esto mismo se deben poner de nuevo los valores y para esto Laravel nos ofrece un auxiliar especial llamado old que podemos usar en el valor del campo.

Aportes 40

Preguntas 4

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Para buenas prácticas, no es recomendable manejar las validaciones en los controllers. Laravel en su documentación propone una manera más óptima. De una vez aprovecho para facilitarles el link de la documentación en español, un gran aporte de Styde

Laravel en Español - Validación de formularios

  • Primero
php artisan make:request StoreExpenseReports

Esto creará una Carpeta Request en Http

/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
    return [
        'title' => 'required|min:3',
    ];
}

En rules, agregarán todas las reglas de validaciones para el modelo correspondiente en este caso Expense Reports

/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
    return true;
}

En el método authorize vamos a poner true, para que nos permita validar y ejecutar la acción del controller. OJO este método es más extenso en ella podemos validar si un user tiene o no permiso de editar y esas cuestiones.

Por ultimo en nuestro controller,

/**
* Store the incoming blog post.
*
* @param  StoreBlogPost  $request
* @return Response
*/
public function store(StoreExpenseReports $request)
{
    // The incoming request is valid...

    // Retrieve the validated input data...
    $validated = $request->validated();
}

En vez de pasar por parámetro Request. Pasamos la clase que creamos al principio con artisan StoreExpenseReports
De esta manera ya está validado y podemos hacer uso de esta misma clase en nuestro metodo Update

Contenido Extra

Modificar mensajes de Error

Dentro de la clase creada al principio crear el método messages y agregar los mensajes de acuerdo al campo y validación de la siguiente.

/**
* Get the error messages for the defined validation rules.
*
* @return array
*/
public function messages()
{
    return [
        'title.required' => 'A title is required',
        'body.required'  => 'A message is required',
    ];
}

Les comparto la función update() con respuestas en español:

    public function update(Request $request, $id)
    {
        $validData = $request->validate(
            ['title' => 'required|min:3'],
            ['title.required' => 'El titulo es requerido por favor', 
            'title.min' => 'El titulo es mínimo 3 caracteres por favor']);

        $report = ExpenseReport::findOrFail($id);
        $report->title = $validData['title'];
        $report->save();

        return redirect('/expense_reports');
    }
public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => 'required|max:255',
            'email' => 'required|email|unique:users',
            'password' => 'required|min:4',
            'role_id' => 'required',
        ];
    }

    public function messages()
    {
        return [
            'name.required' => 'El campo de nombre es requerido',
            'email.required' => 'El campo email es requerido',
            'email.unique' => 'El email ya esta ocupado',
            'password.required' => 'El campo contraseña es requerido',
            'password.min' => 'Minimo 4 caracteres',
            'role_id.required' => 'El campo rol es requerido',
        ];
    }```
Wow wow wow take it easy..... No sabía que Laravel era tan cool

Respuesta al reto:

  1. Modificar el método update dentro del archivo ExpenseReport:
public function update(Request $request, $id)
    {
        $report = ExpenseReport::find($id);

        # Validación. La misma que al guardar
        $validaData = $request->validate([
            'title' => 'required|min:3'
        ]);

        $report->title = $request->get('title');
        $report->save();

        return redirect('/expense_reports');
    }
  1. Agregar el error al template:
<div class="col">
            @if ($errors -> any())
                <div class="alert alert-danger">
                    <ul>
                        @foreach($errors->all() as $error)
                            <li>{{ $error }}</li>
                        @endforeach
                    </ul>
                </div>
            @endif
            <form class="" action="/expense_reports/{{ $report->id }}" method="POST">
                @csrf
                @method('put')
                <div class="form-group">
                    <label for="title">Title:</label>
                    <input type="text" class="form-control" id="title" name="title" placeholder="Title" value="{{ old('title') }}">
                </div>
                <button class="btn btn-primary" type="submit" name="button">Submit</button>
            </form>
        </div>

Excelente, y manejar errores por JS???’’

Héctor menuda pasada de curso que te has marcado!!! MIL GRACIAS!!!

Una forma de validar los campos sin hacerlo en el controlador es mediante un archivo tipo request y desde este mismo enviar los mensajes a la vista en caso de error.

<code>
php artisan make:request NombreRequest

Otra manera de concantenar validaciones es usar un arreglo en lugar del caracter especial pipe “|”. Ejemplo:

$validation = $request->validate([
            'title' => ['required', 'min:3']
        ]);

He aceptado un trabajito como freelance y de lo que he encontrado es que ya tienen una aplicación en PHP 5.5 sin framework hosteado en Google AppEngine. Lo que le he propuesto al cliente es que todo lo adicional que me está pidiendo es hacerlo en un nuevo proyecto de Google AppEngine y con PHP 7.2 con Laravel. Este curso y el de Google Cloud AppEngine me están ayudando un montón en sacar este proyecto adelante.

Apuntes:
Las validaciones son muy importantes en PHP, puesto que de esta manera se asegura que la informacion que ingrese en el sistema sea la correcta, y evita el mal uso del mismo por parte de los atacantes.

Validacion para un insert

Para evitar que un usuario ingrese un formulario vacío (y por ende pueda ver los errores), nos dirigimos al metodo store() y escribimos lo siguiente:

$variableValidacion = $request->validate([
‘nombreInput’ => ‘ValidacionDeLaravel’
]);

Para una mayor documentacion sobre las validaciones, se puede consultar:

https://laravel.com/docs/5.8/validation#available-validation-rules

De esta forma se impedirá que se imprima un error que termine exponiendo el codigo PHP, sin embargo necesitamos imprimir un reporte al usuario acerca del error, para ello nos vamos a la vista y editamos, de la siguiente manera:
@if ($errors->any())
<div class=“alert alert-danger”>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif

Una manera de evitar que el usuario escriba menos caracteres que los deseados, es con ‘min:numeroCaracteres’, y para separar las validaciones se usa el caracter ‘|’, de esta manera:

  • ‘title’ => ‘required|unique:posts|max:255’

Para evitar que la información se pierda al momento de enviar y no pasar el filtro de validación, se puede escribir como valor del formulario 'value="{{ old(‘title’) }}"

Si necesitan que las validaciones se visualizen en español, pueden ir a este Repositorio y poder instalar este paquete mediante composer:

Instalamos el paquete
composer require laraveles/spanish

A continuacion ingresar el siguiente comando
php artisan laraveles:install-lang

Y por ultimo cambiamos en config/app.php la siguiente linea
'locale' => 'es',

Esto nos dejara todos los mensajes de validación en español.

Por otra parte si quiere tener el debuger de esta manera puede ir al siguiente repositorio . El cual es muy util durante el desarrollo de tus aplicaciones, ya en produccion lo configuras para que no se muestre.

Espero les sirva 😃

Para poner los mensajes de validación en español podemos hacerlo así.

composer require laraveles/spanish

luego de un ratito de proceso

php artisan laraveles:install-lang

Y por ultimo cambiamos en config/app.php la siguiente linea

'locale'          => 'es',

Esto nos dejara todos los mensajes de validación en español.

Aquí les dejo el enlace al repo por si necesitan alguna aclaracion

Yo tenia en el caso del editar, en el input del titulo, el titulo que se modificara. Como se puede hacer para tener lo de old tambien es decir mi código esta asi.

<input type="text" value="{{$report->title}}">

este con el fin de que al momento de querer editar, puede ser que solo se quiera editar una letra o algo mínimo.

validación en el edit.blade.php

 @if($errors->any())
                <div class="alert alert-danger">
                    <ul>
                        @foreach($errors->all() as $error)
                            <li>{{ $error }}</li>
                        @endforeach
                    </ul>
                </div>
            @endif

validación en la clase update del controller

$validData = $request->validate([
‘title’ => ‘required|min:3’,
]);

    $report = ExpenseReport::findOrFail($id);
    $report->title = $validData['title'];
    $report->save();

Un ejemplo dentro de los controles de la clase Form de Blade, es incluir a required como una propiedad más de un determinado objeto: Ejemplo:

    <div class="form-group">
        {!! Form::label('title', 'Titulo') !!}
        {!! Form::text('title', null, ['class' => 'form-control', 'placeholder' => 'Título', 'required']) !!}
    </div>

Me encanta este curso

Para cambiar las respuesta :

 $$validDate = $request->validate([
            'title'=>'required|min:3'// sino envia nada
        ],
        [
            'title.required' => 'Es requerido por favor', 
            'title.min' => 'Es minimo 3 por favor', 
        ]
        );

Necesitamos tener validaciones en nuestro proyecto para asegurarnos que los datos ingresados son correctos.

Para profundizar mas se deben leer los metodos de validacion disponibles en laravel https://laravel.com/docs/5.8/validation#available-validation-rules

En el metodo store que se encarga de cargar la informacion aplicamos el metodo validate con la siguiente sintaxis
$variable = $request->validate([
‘nombredelcampo’ => ‘validate’ (O cualquiera de las otras validaciones)
]);

Se pueden concatenar validaciones usando el operador | con la siguiente sintaxis:

En el metodo store que se encarga de cargar la informacion aplicamos el metodo validate con la siguiente sintaxis
$variable = $request->validate([
‘nombredelcampo’ => ‘validate | min:3’ (En este caso se valida que el campo no venga vacio y tenga un largo de al menos 3 caracteres)
]);

Para usar la propiedad de laravel que muestra los errores podemos implementar la sintaxis:
@if ($errors->any())
<div class=“alert alert-danger”>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif (En la vista del formulario)

  • Y para evitar que todos los campos se vacien perdiendo la data luego de las validaciones podemos colocar en los atributos del input ‘value’="{{old(‘title’)}}"

Validaciones en el vista edit

<input type="text" name="title" id="title" class="form-control" value="{{ old('title', $expenseReport->title) }}" placeholder="Type a Title">

Les comparto el link actualizado de las Validaciones en la documentación de Laravel
https://laravel.com/docs/7.x/validation

Les comparto la validación que hice para la edición de reportes, ya que si solo colocamos old(‘title’) no nos carga el valor previo a la edición.

<input type="text" class="form-control" id="title" name="title" placeholder="Type a title" 
                    value="@if($errors->any()){{old('title')}}@else{{$report->title}}@endif">

Excelente!

Recuerden que esta validación esta en la vista de crear, falta agregarlo a Actualizar

cuando valido el title me sale esto

Method validate does not exist.

Yo hice eso
<input type=“text” required class=“form-control” id=“title” placeholder=“Type a title” name=“title”>

Las validaciones no seria mejor si estan dentro del model, porque si queremos hacer una API podemos usar la misma logica de negocio, y no replicar en cada controller.

quien me ayuda !!! me sale error en validation

Buenas compañeros dejo mi pequeño aporte, para validar el email o un dni, pero cuando EDITAMOS un estudiante(en mi caso) les dejo mis validación:

// validamos los campos
$datosValidado = $request->validate([
            'estudianteNombre'      => 'required|min:3|max:50',
            'estudianteApellido'    => 'required|min:3|max:50',
            'estudianteDNI'         => ['required','numeric',Rule::unique('estudiantes','estudianteDNI')
	->ignore($estudiante->estudianteDNI,'estudianteDNI')], 
            'estudianteDomicilio'   => 'required|max:100',
            'estudianteEmail'       => ['email','max:100',Rule::unique('estudiantes','estudianteEmail')
	->ignore($estudiante->estudianteId, 'estudianteId') ], 
            'estudianteTelefono'    => 'max:50',
            'estudianteLocalidad'   => 'required|max:100',
            'estudianteNacimiento'  => 'required|date',
            'estudianteFoto'        => ''
        ]); 
 

lo que estoy haciendo en estudianteDNI y estudianteEmail es que esos campos sean unicó pero que ignore el valor que estoy modificando y así no genere un error.
Saludos.

excelente clase 😄

Excelente clase con las validaciones y los valores anteriores para mejorar la experiencia de usuario

 public function update(Request $request, $id)
    {
        $validData = $request->validate([
            'title' => 'required|min:3'
        ]);

        $report = ExpenseReport::findOrFail($id);
        $report->title = $validData['title'];
        $report->save();

        return redirect('expense_reports');
    }```

Muy buena explicacion

Para colocar los mensajes de erroe en español o, en utilizar uno diseñado por mi, como debo de hacerlo?

Excelente clase, todo muy bien explicado.

Hector que bien

Thanks 😃

Podemos en lugar de dejar el código de los errores en la vista, pasarlos a una nueva vista por ejemplo views/errors/validation.blade.php

//views/errors/validation.blade.php
@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>
                    {{ $error }}
                </li>
            @endforeach
        </ul>
    </div>				
@endif

Y en las vistas create y edit lo que hacemos es un include a la vista nueva

@include('errors.validation')

Y asi continuamos reutilizando código.

Pueden traducir los errores de validación modificando los archivos que se encuentran en la carpeta resources/lang

Aquí nos muestran que hacemos una validación usando el método validate, es correcto, pero si recordamos lo que aprendimos en el curso anterior, la manera correcta es hacer un Request validate mediante la consola para no combinar nuestra lógica de validación con el resto:D!

una muy buena práctica es agregando un FormRequest para el formulario y pasarlo como parámetro al método Store