I cannot understand a point of Laravel's binding system. I know what does dependency injection mean. And it can work even without that weird "bindings", right? I saw in documentation, that binding can return a new object. Why and when I have to use that? Please, explain not very complicated, because I've read documentation and I could not understand the use and the purpose of that bindings. Thanks.
Understanding and using the IoC container is a crucial part in mastering our craft, as it is the core part of a Laravel application. IoC container is a powerful tool for managing class dependencies. It has the power to automatically resolve classes without configuration.
If we take a look at the Laravel documentation, binds are registered using the bind() method. The first argument passed in is a class name, followed by a closure that returns an instantiated instance of that class object.
The Laravel service container is a powerful tool for managing class dependencies and performing dependency injection. Dependency injection is a fancy phrase that essentially means this: class dependencies are "injected" into the class via the constructor or, in some cases, "setter" methods.
Service container is the place our application bindings are stored. And the service providers are the classes where we register our bindings to service container. In older releases of Laravel, we didn't have these providers and people were always asking where to put the bindings.
In general, you might have encountered this a lot while you programming in Laravel based apps. We use bind in the event of reusable classes or objects ( the object is created each time when it is called). So each instance of the class will be different from the previous one.
Laravel is an open-source PHP framework created to start producing web apps more comfortable and durable by built-in features. These features are one of the reasons that make Laravel so extensively used by web developers. A modular packaging system along with dependency management.
What does $this->app->singleton (); method do? The singleton method binds a class or interface into the service container so that Laravel can maintain dependency (when using an interface as the constructor parameter). (Actually Singleton is a design pattern.
The singleton method binds a class or interface into the service container so that Laravel can maintain dependency (when using an interface as the constructor parameter). (Actually Singleton is a design pattern. Singleton implementation always returns the same object on subsequent calls instead of a new instance).
And it can work even without that weird "bindings", right?
Not really. Sure it can work just fine if the required dependencies are simple to instantiate. Let's say you have this simple class Foo
stored in app
directory:
<?php namespace App; class Foo { public function hello() { return 'Hello World'; } }
You can type hinted this class without binding it first in the container. Laravel will still be able to resolve this class. Let's say you type-hinted it like this in the routes:
Route::get('/foo', function (App\Foo $foo) { return $foo->hello(); // Hello World });
We can even go further, let's say this Foo
class required another simple class Bar
. Our Bar
class looks like this:
<?php namespace App; class Bar { public function hello() { return 'bar'; } }
And our Foo
class looks like this now:
<?php namespace App; class Foo { public function __construct(Bar $bar) { $this->bar = $bar; } public function hello() { return $this->bar->hello(); } }
Will Laravel be able to resolve the type-hinted Foo
class now? YES! Laravel will still be able to resolve this Foo
class.
Now the issue will come in when our Foo
class needs slightly more complex dependencies that need to be configured. Imagine that our Foo
class simply need the name of our application. Sure you can simply use config('app.name')
within the class's method, but imagine that this can be an HTTP client that requires a configuration array to instantiate.
<?php namespace App; class Foo { public function __construct($appName) { $this->appName = $appName; } public function hello() { return "Hello {$this->appName}"; } }
Will Laravel be able to solve this class now? NOPE. Service Container to the rescue! You can teach Laravel how to resolve this Foo
class by binding it in service container. You can define the binding within the register
method on app\Providers\AppServiceProvider.php
file:
public function register() { $this->app->bind(\App\Foo::class, function ($app) { // Pass the application name return new \App\Foo($app->config['app.name']); }); }
And sometimes, you don't want multiple instances to be created. Like our Foo
class for instance, there's no need for multiple instances for this kind of class. In this case, we can bind it with singleton method.
$this->app->singleton(\App\Foo::class, function ($app) { return new \App\Foo($app->config['app.name']); });
More Important Usage
But the more important usage of this service container is that we can bind an interface to it's implementation. Let's say we have this PaymentProcessorInterface
with pay
method:
<?php namespace App; interface PaymentProcessorInterface { public function pay(); }
Then we have the implementation of this interface named StripeProcessor
:
<?php namespace App; class StripeProcessor implements PaymentProcessorInterface { public function pay() { return 'pay with stripe'; } }
With service container, we can bind the PaymentProcessorInterface
to StripeProcessor
class:
$this->app->bind(\App\PaymentProcessorInterface::class, function () { return new \App\StripeProcessor(); });
We can then type-hinted PaymentProcessorInterface
within our code:
Route::get('/pay', function (App\PaymentProcessorInterface $paymentProcessor) { return $paymentProcessor->pay(); // pay with stripe });
This way we can easily swap the PaymentProcessorInterface
implementation. Let's say we want to change the payment processor to Paypal then we have this PaypalProcessor
class.
<?php namespace App; class PaypalProcessor implements PaymentProcessorInterface { public function pay() { return 'pay with paypal'; } }
All we have to do is update the binding:
$this->app->bind(\App\PaymentProcessorInterface::class, function () { return new \App\PaypalProcessor(); });
Hope this gives you some ideas.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With