What is a PHP Interface?
An interface in PHP is a blueprint for classes. It defines a contract that any implementing class must adhere to, specifying methods that must be implemented but not providing the method bodies. Interfaces ensure a consistent structure across different classes and enable polymorphism by allowing multiple classes to be treated through a common interface. You can read more about it here
Use without binding
Let’s first talk about how to use interfaces without binding in laravel.
1.Define an Interface:
Create an interface in the AppContracts directory.
namespace AppContracts;
interface PaymentGatewayInterface {
public function charge($amount);
}
2.Implement the Interface with Additional Methods:
namespace AppServices;
use AppContractsPaymentGatewayInterface;
class StripePaymentGateway implements PaymentGatewayInterface {
public function charge($amount) {
// Logic to charge using Stripe
return “Charged {$amount} using Stripe”;
}
}
3.Inject the Implementation Manually:
When you instantiate the controller or the class that requires the interface, manually provide the implementation.
namespace AppHttpControllers;
use AppContractsPaymentGatewayInterface;
use AppServicesStripePaymentGateway;
class PaymentController extends Controller {
protected $paymentGateway;
public function __construct(PaymentGatewayInterface $paymentGateway) {
$this->paymentGateway = $paymentGateway;
}
public function charge($amount) {
return $this->paymentGateway->charge($amount);
}
}
use AppHttpControllersPaymentController;
use AppServicesStripePaymentGateway;
Route::get(‘/charge/{amount}’, function ($amount) {
$paymentGateway = new StripePaymentGateway();
$controller = new PaymentController($paymentGateway);
return $controller->charge($amount);
});
Example with binding and benefits of the approach
Laravel’s service container can automatically resolve dependencies for you, reducing boilerplate code. Check this example.
namespace AppProviders;
use IlluminateSupportServiceProvider;
use AppContractsPaymentGatewayInterface;
use AppServicesStripePaymentGateway;
class AppServiceProvider extends ServiceProvider {
public function register() {
$this->app->bind(PaymentGatewayInterface::class, StripePaymentGateway::class);
}
public function boot() {
//
}
}
namespace AppHttpControllers;
use AppContractsPaymentGatewayInterface;
use AppServicesStripePaymentGateway;
class PaymentController extends Controller {
protected $paymentGateway;
public function __construct(PaymentGatewayInterface $paymentGateway) {
$this->paymentGateway = $paymentGateway;
}
public function charge($amount) {
return $this->paymentGateway->charge($amount);
}
}
With this binding in place, you don’t need to manually instantiate StripePaymentGateway. So this code is enough inside routes.
use AppHttpControllersPaymentController;
Route::get(‘/charge/{amount}’, [PaymentController::class, ‘charge’]);
In this example we have used service binding in Laravel. Service binding is used to register a concrete implementation for a given interface or abstract class in Laravel’s service container. This allows Laravel to automatically resolve dependencies and inject the appropriate implementations when needed.