how to validate user Input with Laravel validation (Part – II)

how to validate user Input with Laravel validation

Hi guys,

Today we are learning how to validate user Input with Laravel validation. Laravel allows you to handle incoming data from requests and send back error messages. For this topic, I have created two parts. In the first article, we are learning Form Request validation and displaying Validation Errors. The second article will study creating manual validators, working with error messages, and Custom Validation Rules. So let’s begin.

Manually Creating Validators:-

If you do not want to use the validate method on the request, you may create a validator instance manually.

 <?php
 namespace App\Http\Controllers;

 use App\Http\Controllers\Controller;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Validator;

 class PostController extends Controller
 {
    /**
      * Store a new blog post.
      *
      * @param Request $request
      * @return Response
      */
      public function store(Request $request)
      {
          $validator = Validator::make($request->all(), [
                   'title' => 'required|unique:posts|max:255',
                   'body' => 'required',
            ]);
           if ($validator->fails()) {
                return redirect('post/create')
                    ->withErrors($validator)
                    ->withInput();
            }

            // Store the blog post
     }
 }

We are passing two arguments to the make() method. The first argument is the data, which we want to validate. The second argument is validation rules which apply to the data. Using the withErrors() method, we flash the error messages to the session.

You would like to create a validator instance manually. It still takes advantage of the automatic redirection offered by the request’s validate() method.

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

 Validator::make($request->all(), [
                 'title' => 'required|unique:posts|max:255',
                 'body' => 'required',
    ])->validateWithBag('post');

Named Error Bags:

You have multiple forms inside a single page and want to display the respective error message in the Respective Form.

 return redirect('register')->withErrors($validator, 'login');

You can access the $errors variable on view.

 {{ $errors->login->first('email') }}

After validation hook:

The validator allows you to attach a callback to run after it completes validation. This feature allows you to add more validation rules to the fields and add more error messages.

 $validator = Validator::make(…);

 $validator->after(function ($validator) {
        if ($this->somethingElseIsInvalid()) {
             $validator->errors()->add('field', 'Something is wrong with this field!');
        }
 });

 if ($validator->fails()) {
   //
 }

Working with error messages:-

The $errors variable is automatically available to all views. It is an instance of MessageBag class with different methods for working with error messages. We can retrieve the first error message using the first() method.

 $errors = $validator->errors();

 echo $errors->first('email');

You can use the get() method to retrieve all error messages for a field.

 foreach ($errors->get('email') as $message) {
   //
 }

To retrieve an array of all messages for all fields, use the all() method.

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

To check if any error messages exist for this field, use the has() method.

 if ($errors->has('email')) {
           //
 }

Custom error message:

You can create a custom error message for validation. In that case, you can pass the third argument as custom messages to the make() method.

 $messages = [
    'required' => 'The :attribute field is required.',
 ];

 $validator = Validator::make($input, $rules, $messages);

The actual name of the field will replace the ‘:attribute’ placeholder under validation. Sometimes you have to customize the error message only for a specific entity using “DOT” notation.

 $messages = [
     'email.required' => 'We need to know your email address!',
 ];

You may pass custom attributes as the fourth argument to the validator::make() method:

 $customAttributes = [
    'email' => 'email address',
 ];

 $validator = Validator::make($input, $rules, $messages,$customAttributes);

Suppose, We can store credit card numbers according to their payment type. According to the payment type, we require some fields using the required_if keyword.

 $request->validate([
    'credit_card_number' => 'required_if:payment_type,cc'
 ]);

Conditionally Adding Rules:-

You do not validate a field if another field value exists. It can be accomplished by using the exclude_if validation rule.

 $v = Validator::make($data, [
          'has_appointment' => 'required|bool',
          'appointment_date' => 'exclude_if:has_appointment,false|required|date',
          'doctor_name' => 'exclude_if:has_appointment,false|required|string',
       ]);

You can also use the exclude_unless validation rule for not validating a field unless another field exists value.

 $v = Validator::make($data, [
         'has_appointment' => 'required|bool',
         'appointment_date' => 'exclude_unless:has_appointment,true|required|date',
         'doctor_name' => 'exclude_unless:has_appointment,true|required|string',
      ]);

You want to run validation checks against a field only if the variable is present in the input. Using the ‘sometimes’ keyword.

 $v = Validator::make($data, [
          'email' => 'sometimes|required|email',
       ]);

Validating Arrays:

If the incoming HTTP Request contains a photos[profile] field, you may validate it so

 $validator = Validator::make($request->all(), [
                    'photos.profile' => 'required|image',
               ]);

Custom Validation Rules:-

You can create your own rules for your application. To generate a new rule object, you can run the following command:

 php artisan make:rule Uppercase

It will generate an Uppercase file inside the app\rules directory. Rule class contains two methods: The passes() method receives the attribute value and name and should return a boolean value. The message() method should return a validation error message that should be received when validation fails.

 <?php
 namespace App\Rules;

 use Illuminate\Contracts\Validation\Rule;

 class Uppercase implements Rule
 {
     /**
      * Determine if the validation rule passes.
      *
      * @param string $attribute
      * @param mixed $value
      * @return bool
      */
      public function passes($attribute, $value)
      {
          return strtoupper($value) === $value;
      }
      /**
       * Get the validation error message.
       *
       * @return string
       */
       public function message()
       {
           return 'The :attribute must be uppercase.';
       }
 }

You can pass the instance of your custom rules in the validate() method.

 use App\Rules\Uppercase;

 $request->validate([
      'name' => ['required', 'string', new Uppercase],
  ]);

Using Closures:

You want to use a custom rule at once. You can use a closure instead of creating an object.

 $validator = Validator::make($request->all(), [
           'title' => [
                       'required',
                       'max:255',
                       function ($attribute, $value, $fail) {
                         if ($value === 'foo') {
                              $fail($attribute.' is invalid.');
                           }
                        },
                      ],
                ]);

Using extension:

Another method of registering custom validation rules is using the extend() method.

 <?php

 namespace App\Providers;

 use Illuminate\Support\ServiceProvider;
 use Illuminate\Support\Facades\Validator;

 class AppServiceProvider extends ServiceProvider
 {
   /**
    * Register any application services.
    *
    * @return void
    */
    public function register()
    {
      //
    }
    
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
         Validator::extend('foo', function ($attribute, $value, $parameters,         $validator) {
               return $value == 'foo';
        });
    }
 }

The extend() method needs four parameters: $attribute being validated, $value being the attribute, $parameter being an array of rules, and $validator instance.

You may pass a class name and method to extend the function instead of closure as we did on the route file.

 Validator::extend('foo', 'FooValidator@validate');

For a rule to run, even when an attribute is empty, a rule must imply that the attributes are required. To create such an “implicit” extension, use the Validator::extendImplicit() method:

 Validator::extendImplicit('foo', function ($attribute, $value, $parameters,      $validator) {
           return $value == 'foo';
     });

You want to make a rule object on an attribute. If the variable is empty, then you should implement the ImplicitRule interface on your custom rule. The interface does not contain any methods that you need to implement.

I am sure this article (how to validate user input with Laravel validation) will help you better understand the Custom Validation rules and create custom rules in Laravel. I have followed this link for this article. If you have any doubts, then comment below then I will reply as per as possible.

Thank you for reading this article. Please share this article with your colleagues and friends. So it better understands the Validation in Laravel. That’s it for the day. Stay Connected!

Cheers,

Loading

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top