Laravel Service Provider describes problems encountered when developing and setting delayed loading. laravelprovider
Preface
This article mainly introduces some problems encountered when Laravel Service Provider sets delayed loading. All of these problems are due to actual project requirements. Recently, when developing the laravel-database-logger package, when the ServiceProvider defer attribute is set to true, the middleware registered in the register method is invalid.
Class ServiceProvider extends \ Illuminate \ Support \ ServiceProvider {protected $ defer = true; public function register () {$ this-> mergeConfigFrom (_ DIR __. '/.. /config. php ', 'ibrand. dblogger '); $ this-> app-> singleton (DbLogger: class, function ($ app) {return new DbLogger ();}); // when $ defer is set to true, an error is returned when databaselogger middleware is referenced in the route, prompting databaselogger class not found. $ this-> app [\ Illuminate \ Routing \ Router: class]-> middleware ('databaselogger ', Middleware: class);} public function provides () {return [DbLogger: class] ;}}
When the problem occurs, it is suspected that the defer attribute is set to true, and the source code is modified immediately.protected $defer = true;
The code is commented out, and the result is still a promptdatabaselogger class not found.
Laravel does not register this ServiceProvder.
Next, I tried the following methods to solve the problem:
1. Verify if the Code itself has problems
Register your own ServiceProvider In the normally registered AppServiceProvider
public function register() { // $this->app->register(\Ibrand\DatabaseLogger\ServiceProvider::class); }
The registration result is normal.
2. Research source code
In config/app. php, providers registration is invalid, but it is valid in other serviceproviders, which indicates other problems.
Find the registerConfiguredProviders method by studying the Illuminate \ Foundation \ Application source code:
Laravel reads the providers in config/app. php In this method and loads the content to ProviderRepository.
(new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath())) ->load($providers->collapse()->toArray());
Focus on$this->getCachedServicesPath()
Through the source code, Laravel determines how to register ServiceProvider Based on the bootstrap/cache/services. php file.
Now I thought about why I commented out //protected $defer = true;
The reason why the code is still invalid.
So in order to make//protected $defer = true;
Code execution is required
php artisan clear-compiled php artisan optimize
Then the problem is solved, and the principle of ServiceProvider is further understood.
Therefore, it is strictly prohibited to register middleware, route, and other operations when you are about to use a delay to load ServiceProvider. After changing the value of the defer attribute, you must executephp artisan clear-compiled
Andphp artisan optimize
To update the ServiceProvider cache.
3. Why is the registration in AppServiceProvider valid?
Willingness to be simple, because AppServiceProvider does not delay loading, so it will not delay loading when executing the register Method in AppServiceProvider to register a new ServiceProvider.
Summary
Exercise caution when using delayed loading ServiceProvider
After changing the defer attribute value, you must executephp artisan clear-compiled
Andphp artisan optimize
To update the ServiceProvider cache.
It is strictly prohibited to register middleware and route in the delayed loading ServiceProvider.
Well, the above is all the content of this article. I hope the content of this article has some reference and learning value for everyone's learning or work. If you have any questions, please leave a message to us, thank you for your support.