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 App\Contracts directory.
// app/Contracts/PaymentGatewayInterface.php namespace App\Contracts; interface PaymentGatewayInterface { public function charge($amount); }
2.Implement the Interface with Additional Methods:
// app/Services/StripePaymentGateway.php namespace App\Services; use App\Contracts\PaymentGatewayInterface; 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.
// app/Http/Controllers/PaymentController.php namespace App\Http\Controllers; use App\Contracts\PaymentGatewayInterface; use App\Services\StripePaymentGateway; class PaymentController extends Controller { protected $paymentGateway; public function __construct(PaymentGatewayInterface $paymentGateway) { $this->paymentGateway = $paymentGateway; } public function charge($amount) { return $this->paymentGateway->charge($amount); } }
// routes/web.php use App\Http\Controllers\PaymentController; use App\Services\StripePaymentGateway; 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.
// app/Providers/AppServiceProvider.php namespace App\Providers; use Illuminate\Support\ServiceProvider; use App\Contracts\PaymentGatewayInterface; use App\Services\StripePaymentGateway; class AppServiceProvider extends ServiceProvider { public function register() { $this->app->bind(PaymentGatewayInterface::class, StripePaymentGateway::class); } public function boot() { // } }
// app/Http/Controllers/PaymentController.php namespace App\Http\Controllers; use App\Contracts\PaymentGatewayInterface; use App\Services\StripePaymentGateway; 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.
// routes/web.php use App\Http\Controllers\PaymentController; 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.
Top comments (0)