If there is one thing at the heart of the Laravel framework, it is surely the service container. Understanding the concept of a service container is so important for us to use Laravel that it should be said that understanding the concept of a service container is an important condition to distinguish whether or not to start laravel. This is because the framework is built on top of the service container.
The Laravel service container is like a highly automated factory, where you customize the models and use specific interfaces to make the things you need.
Because of the use of service containers, most objects in Laravel are instantiated like this:
$obj1 = $container->make('class1', 'class2');
$obj2 = $container->make('class3', 'class4');
Copy the code
However, without using a service container, this can be done as well:
$obj1 = new class1(new class2());
$obj2 = new class3(new class4());
Copy the code
So what are the advantages of using a service container? Here are some specific examples to analyze its advantages:
Example 1: Send an email
We encapsulate the ability to send mail into a class that instantiates and calls the send method when needed.
The following are common ways of not using laravel service containers:
$EmailService = $EmailService = $EmailService = $EmailService = $EmailService = $EmailService = $EmailService = $EmailService = $EmailService = $EmailService new EmailService(); $emailService->send();Copy the code
After using the Laravel service container:
$this->app->bind('emailService', function ($app) { return new EmailService(); }); $emailService = app('emailService') $emailService = app('emailService'); $emailService->send();Copy the code
This makes our code simpler, and thanks to the middle tier, increased flexibility (decoupling) makes it easier to both test (where we can fake classes to replace the EmailService class) and optimize the EmailService class.
$this->app->bind('emailService', function ($app) {return new SupperEmailService(); });Copy the code
The rest of the calls were left untouched, and if we didn’t have this binding operation, we would have to make changes everywhere the mail service was used.
$emailService = new SupperEmailService(); $emailService->send();Copy the code
Example 2. Implement singleton pattern
Again, for performance reasons, you need the SupperEamilService class to implement the singleton pattern, so without using the Laravel service container, you change the SupperEmailService class to the following:
Class SupperEamilService{// Create a static private $instance; Private function __clone(){} static public function $instance (Uni){$instance (Uni){$instance (Uni); self::$instance instanceof self) { self::$instance = new self(); } return self::$instance; Public function send(){}}Copy the code
In addition, since the SupperEamilService class constructor is now private and cannot be used to instantiate objects with the new keyword, the SupperEmailService class should be instantiated in each place:
$emailService=SupperEmailService::getInstance();
$emailService->send();
Copy the code
Laravel service containers naturally support singletons. Here’s how laravel works:
Singleton $this->app->singleton('emailService', function ($app) {return new SupperEmailService(); });Copy the code
Singletons can even be implemented with a single line of code that changes the bind method to singleton, which is conveniently pulled out of the container.
The traveler went on a trip
This example assumes that a traveler is traveling to Tibet. He can take the train or walk.
Do not use laravel service containers:
<? php interface TrafficTool { public function go(); } class Train implements TrafficTool { public function go() { echo "train...." ; } } class Leg implements TrafficTool { public function go() { echo "leg.." ; }} class Traveller {/ * * * @ var legs | null | "Train" * * travel tools/protected $_trafficTool; public function __construct(TrafficTool $trafficTool) { $this->_trafficTool = $trafficTool; } public function visitTibet() { $this->_trafficTool->go(); }}Copy the code
When travelers want to travel by train, we usually write:
<? php $train = new Train(); $tra = new Traveller($train); $tra->visitTibet();Copy the code
This is actually pretty good because the dependency on the travel tool has been transferred externally through the interface. However, using new to instantiate objects still creates dependencies. Traveller must have a $trafficTool before creating a Traveller. Traveller depends on trafficTool. When using new to instantiate Traveller, there is a coupling between Traveller and trafficTool. In this way, the two components cannot be separated.
Now let’s see how this is implemented using the Laravel service container:
Bind classes in the service container
<? php namespace App\Providers; use Laravel\Lumen\Providers\EventServiceProvider as ServiceProvider; Class RepositoryServiceProvider extends ServiceProvider {public function register () {/ / in a service container binding class $this - > app - > bind ( 'TrafficTool', 'Train'); $this->app->bind('Traveller', 'Traveller'); }}Copy the code
Instantiate an object
<? $tra = app()->make('Traveller'); $tra = app()->make('Traveller'); $tra->visitTibet();Copy the code
When we use the service container to get the object of the travel class, the container automatically injects the parameters required by the object. Previously I only had to bind specific classes, which is true automation and completely decouples the travel class from the travel utility class. When we need to change the mode of travel, we just need to change the binding.
conclusion
The laravel service container provides a few simple examples, but if you can fully understand and master the Laravel service container, it will be much more convenient in real life development. Of course, it is not perfect, in short, the actual use of the strengths and weaknesses is the key.
I hope the above content can help you. Many PHPer will encounter some problems and bottlenecks when they are advanced, and they have no sense of direction when writing too many business codes. I have sorted out some information, including but not limited to: Distributed architecture, high scalability, high performance, high concurrency, server performance tuning, TP6, Laravel, Redis, Swoft, Kafka, Mysql optimization, shell scripting, Docker, microservices, Nginx, etc. Many knowledge points can be free to share with you