Laravel Validation

Laravel provides a different way to validate the application`s incoming data.

Laravel base controller class uses a ValidatesRequests that provides an easy method to validate incoming HTTP request with many powerful validation rules.

Defining the Routes

The following routes are defined in our app/Http/routes.php file:

// Display a form to create a post.
 Route::get('post/create', 'PostController@create');
 // Store a new post.
 Route::post('post', 'PostController@store'); 

The GET route will present a form for the user which creates a new post and the POST route that will store the new post in the database.

Creating the Controller

A simple controller which handles these routes. We will leave the store method empty for now:

<?php
 namespace App\Http\Controllers;
 use Illuminate\Http\Request;
 use App\Http\Controllers\Controller;
 class PostController extends Controller
 {
     /**
      * Show the form to create a new post. 
      *
      * @return Response
      */
 public function create()
     {
 return view('post.create'); 
     }
     /**
      * Store a new post.
      *
      * @param  Request  $request
      * @return Response 
      */
 public function store(Request $request)
     {
         // Validate and store the blog post...
     }
 } 

The Validation Logic

Now we can fill our store method with the logic that validates the new post.

Application`s base controller will be located in (App\Http\Controllers\Controller) class.

It provides an easy way to validate method in all of our controllers. 

An incoming method requests and a validation rule is accepted by the validate method.

If the validation rules pass, our code will keep executing normally.

An exception will be thrown, and the error response will automatically sent to the user only if the validation fails.

/**
  * Store a new post.
  *
  * @param  Request  $request
  * @return Response
  */
 public function store(Request $request) 
 {
     $this->validate($request, [
         'title' => 'required|unique:posts|max:255',
         'body' => 'required',
     ]);
 // Thepost is valid, store in database...
 } 

We pass the incoming HTTP request and desired validation rules into the validate method.

The proper response will automatically be generated only if the validation fails.

And if the validation passes, our controller will continue executing normally.

First Validation Failure

The first validation failure stops running validation rules on an attribute.

Assign the bail rule to the attribute:

$this->validate($request, [
     'title' => 'bail|required|unique:posts|max:255',
     'body' => 'required',
 ]); 

In the above example, if the required rule on the title attribute fails, then the unique rule will not be checked.

Rules will be validated in order they are assigned.

Displaying The Validation Errors

The $errors variable will be a reference to Illuminate\Support\MessageBag.

Note: 0

The $errors variable to the view by the Illuminate\View\Middleware\ShareErrorsFromSession middleware that is provided by the web middleware group. 

This middleware is activated an $errors variable which will always available in our view, it allow us easily assume the $errors variable that is always defined.

<!-- /resources/views/post/create.blade.php -->
 <h1>Create Post</h1>
 @if (count($errors) > 0)
 <div class="alert alert-danger">
 <ul>
             @foreach ($errors->all() as $error) 
 <li>{{ $error }}</li>
             @endforeach
 </ul>
 </div>
 @endif 
 <!-- Create Post Form --> 

The @error Directive

The @error Blade directive checks if validation error messages exist for a given attribute.

A @error directive, we echo the $message variable that display the error message:

<!-- /resources/views/post/create.blade.php -->
 <label for="title">Title</label>
 <input id="title" type="text" class="@error('title') is-invalid @enderror">
 @error('title')
 <div class="alert alert-danger">{{ $message }}</div>
 @enderror 

Form Request Validation

Creating Form Requests

 Form requests are custom request classes which contain validation logic.

To create a form request class, we use the make:request Artisan CLI command:

php artisan make:request StorePost

The generated class will be located in the app/Http/Requests directory.

It will be created when we run the make:request command only if the app/Http/Requests directory does not exist.

public function rules()
 {
 return [
         'title' => 'required|unique:posts|max:255',
         'body' => 'required',
 ];
 } 

The incoming form request is validated before calling the controller method, it means that we do not need to disarrange our controller with any validation logic:

/**
  * Store the incoming post.
  *
 * @param  StorePost  $request
  * @return Response
  */
 public function store(StorePost $request) 
 {
     // The incoming request is valid...
     // Retrieve the validated input data...
     $validated = $request->validated();
 } 

A redirect response will be generated to send the user at the previous location only if the validation fails. The errors will be flashed to the session, so they are available for display.

A HTTP response with 422 status code then it will be returned to the user by including a JSON representation of the validation errors if the request was an AJAX request.

Authorizing Form Requests

The form request class contains an authorize method.

We can check the authenticated user has the authority to update a given resource.

/**
 * Specify if the user is authorized to make this request.
  *
  * @return bool
  */
 public function authorize() 
 {
 $comment = Comment::find($this->route('comment'));
 return $comment && $this->user()->can('update', $comment);
 } 

The base Laravel request extends by all form requests, we use the user method to access the authenticated user.

For callingroute method in the above example, the requested method access the URI parameters which are specified on the route, like as the {comment} parameter.

Route::post(‘comment/{comment}’);

If the authorize method returns false, then an HTTP response with the status code 403, it will be automatically return, and our controller method will not execute.

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

In the above example, the authorization logic simply returnstrue from the authorize method.

Working With Error Messages

The errors method on a Validator, an Illuminate\Support\MessageBag has several methods for working with error messages.

Retrieving the First Error Message

We use the first method for retrieving first error message of the given field:

$messages = $validator->errors();
echo $messages->first(‘email’); 

Retrieving All Error Messages

We use the get method to retrieve an array of all the messages to a given field:

foreach ($messages->get(‘email’) as $message)
 {
 // statement
 } 

Retrieving All Error Messages

We use the all method to retrieve an array of all messages for all the fields:

foreach ($messages->all() as $message)
 {
 //statement
 }