In this tutorial, I will give you a clear explanation of what is interface and when to use this feature in our application. I will give you a complete solid example of the interface in Laravel. As I going to give example with Laravel and the topic is the interface, so you need a clear understanding of the Laravel service provider and the service container to learn dependency injection in Laravel.

If you have doubts about these topics, I will recommend you, please read the below content which I have written about Laravel service containers and service providers. 

Recommended: What Is Service Container And When To Use It In Laravel

 

Recommended: Central Place Of Laravel | Service Provider Explanation

The interface gives us 100% data abstractions. Do you know what is the data abstractions in object oriented programming? Abstraction means the process of data hiding. So, we use an interface in our applications for hiding our data by creating a polymorphic object using the interface. Confused? We can say, in the Laravel interface is a contract for what methods will be used in a specific class to create a polymorphic object.

real-life-interface-example-laravel.png

Why, when we will use an interface in our application?

Let's take an example. Assuming we have a payment system in our applications to create a subscription plan. So we have a payment form like the below:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Laravel Interface Example</title>
    </head>
    <body class="antialiased">
    <form action="{{ route('payment') }}" method="post">
        @csrf
        <select name="payment_type">
            <option value="paypal">Paypal</option>
            <option value="stripe">Sripe</option>
            <option value="wire_transfer">Wire</option>
        </select>
        <input type="submit" value="Pay">
    </form>
    </body>
</html>

 

Look, there is a payment form and there are multiple options to pay. So if you process payment without the interface, then how we can process this payment in our controller? Look, the scenario will be like that:

app\Http\Controllers\PaymentController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PaymentController extends Controller
{
   public function pay(Request $request)
   {
        if($request->has('payment_method')) {
            if($request->payment_type == 'paypal') {
                //charge with paypal
            }
            if($request->payment_type == 'stripe') {
                //charge with stripe
            }
            if($request->payment_type == 'wire_transfer') {
                //charge with wire
            }
            // and more if any payment service arises
        }
   }
}

 

Look, we don't know which payment option is going to use by the customer. So we need so many if conditions in our controller. But what if we have a payment service for solving this payment process? Let's try with the payment service interface.

App\Contracts\PaymentServiceContract.php

<?php

namespace App\Contracts;

interface PaymentServiceContract
{   
    public function setConfig();

    public function setAmount($amount);

    public function setDescription($description);

    public function charge();
}

 

Look at that above interface. We have created some common functions that are always needed when we need to process a payment. We can now use this interface in every type of payment service. 

Remember: It is a good practice to create a concrete class then implemets interface from that concrete class and extend this concrete class by the main class.

 

Recommended: Complete Guide On Pipeline Design Pattern In Laravel

 

So now create a service class, and implements this interface like below:

App\Service\PaymentService.php

<?php 

namespace App\Service;

use App\Contracts\PaymentServiceContract;

class PaymentService implements PaymentServiceContract
{
    public function setAmount($amount)
    {
        $this->amount = $amount;

        return $this;
    }

    public function setDescription($description = '')
    {
        $this->description = $description;

        return $this;
    }

    public function setConfig()
    {
        return $this;
    }

    public function charge()
    {
        return $this;
    }
}

 

Now look at that, we have implements our interface from our service class. Now all are ok, just we will create every type of payment class, and then we will process payment according to the user's request. 

Now create your payment service like:

App\Service\StripePaymentService.php

<?php 

namespace App\Service;

use App\Service\PaymentService;

class StripePaymentService extends PaymentService
{
    //charge with stripe and do what you need
}

 

App\Service\PaypalPaymentService.php

<?php 

namespace App\Service;

use App\Service\PaymentService;

class PaypalPaymentService extends PaymentService
{
    //charge with Paypal and do what you need
}

 

App\Service\WirePaymentService.php

<?php 

namespace App\Service;

use App\Service\PaymentService;

class WirePaymentService extends PaymentService
{
    //charge with wire and do what you need
}

 

Now all are set to go. Now just we have to resolve our dependency from our service provider to find out what payment request is made by the user and then according to the users request, we will bind the payment class with the interface to create a polymorphic object, and then we will process payment. So open update app service provider like:

app\Providers\AppServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        if (request()->has('payment_method')) {
            $className = $this->resolvePaymentDependency(request()->get('payment_method'));
            $this->app->bind(PaymentServiceContract::class, $className);
        }
    }

    public function boot()
    {
        //
    }

    private function resolvePaymentDependency($class_name)
    {
        switch ($class_name) {
            case 'stripe':
                return \App\Service\StripePaymentService::class;
            case 'paypal':
                return \App\Service\PaypalPaymentService::class;
            case 'wire_transfer':
                return \App\Service\WirePaymentService::class;
        }

        throw new \ErrorException("Error: Payment Method {$class_name} Not Found.");
    }

}

 

Now all are set to go. We have automatically injected our payment class by the service provider and the service container. Now look at that our payment controller code:

app\Http\Controllers\PaymentController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Contracts\PaymentServiceContract as Payment;

class PaymentController extends Controller
{
   public function pay(Request $request, Payment $payment)
   {    
        $payment->setAmount(30)
                ->setDescription("Demo payment from {$request->payment_type}")
                ->setConfig()
                ->charge();
   }
}

 

Read also: Laravel Passwordless Login | Login With Username In Laravel

 

Conclusion

Look at the code. How cool it is. This is the use case of the interface in any application. We have created a polymorphic $payment object using the interface by binding it with the class with this interface using the service container.