Home>Article>Backend Development> Solutions to problems encountered when setting up lazy loading during Laravel Service Provider development
Recently when developing the laravel-database-logger package, I found that setting the ServiceProviderdefer
property totrue
will result in registration in theregister
method. Themiddleware
is invalid. This article mainly shares with you the solutions to the problems encountered when setting up lazy loading during Laravel Service Provider development. I hope it can help everyone.
class ServiceProvider extends \Illuminate\Support\ServiceProvider { protected $defer = true; public function register() { $this->mergeConfigFrom( __DIR__ . '/../config/config.php', 'ibrand.dblogger' ); $this->app->singleton(DbLogger::class, function ($app) { return new DbLogger(); }); //当 $defer 设置为 true 时,在路由中引用 databaselogger middleware 会报错,提示 databaselogger class not found. $this->app[\Illuminate\Routing\Router::class]->middleware('databaselogger', Middleware::class); } public function provides() { return [DbLogger::class]; } }
When the problem occurred, I suspected that it was caused by setting thedefer
attribute totrue
. I immediately modified the source code toprotected $defer = true;
code is commented out, and the result is still the promptdatabaselogger class not found.
, indicating that Laravel has not registered thisServiceProvder
The next step is what to do To solve this problem, I tried the following methods:
1. Verify whether there is a problem with your own code
Register yourself in the normally registeredAppServiceProvider
After theServiceProvider
public function register() { // $this->app->register(\Ibrand\DatabaseLogger\ServiceProvider::class); }
was registered, everything was normal.
2. Study the source code
The registration ofproviders
inconfig/app.php
is invalid, but in otherServiceProvider# If the registration in ## is valid, it means there is another problem.
registerConfiguredProvidersmethod by studying the
Illuminate\Foundation\Applicationsource code:
config/ in this methodproviders
content in app.phpand
loadto
ProviderRepository.
(new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath())) ->load($providers->collapse()->toArray());The key point is
$this->getCachedServicesPath(). Through the source code, we found that Laravel determines how to register based on the
bootstrap/cache/services.phpfile
ServiceProvider.
//protected $defer = true;code was still invalid.
//protected $defer = true;to be effective, the code needs to be executed.
php artisan clear-compiled php artisan optimizeAfter that, the problem is solved and I have a deeper understanding of ServiceProvider. principle. So remember: If you plan to use delayed loading
ServiceProvider, it is strictly prohibited to register middleware, route and other series of operations. At the same time, after changing the
deferattribute value, you need to execute
php artisan clear-compiledand
php artisan optimizeto update the ServiceProvider cache.
3. Why is registration in AppServiceProvider valid?
It is very simple, becauseAppServiceProvideris not delayed loading, so the
registermethod in
AppServiceProvideris executed to register a new one
ServiceProviderwill not be delayed loaded either.
ServiceProvider
deferAfter setting the attribute value,
php artisan clear-compiledand
php artisan optimizeneed to be executed to update the ServiceProvider cache.
middlewareand
routein lazy-loaded
ServiceProvider.
Detailed explanation of laravel5's method of creating service provider and facade
Laravel Service Providers question
How to create service provider and facade in laravel5
The above is the detailed content of Solutions to problems encountered when setting up lazy loading during Laravel Service Provider development. For more information, please follow other related articles on the PHP Chinese website!