Recently when developing the laravel-database-logger package, I found that setting the ServiceProvider defer
property to true
will result in registration in the register
method. The middleware
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 the defer
attribute to true
. I immediately modified the source code to protected $defer = true;
code is commented out, and the result is still the prompt databaselogger class not found.
, indicating that Laravel has not registered this ServiceProvder
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 registered AppServiceProvider
After the ServiceProvider
public function register() { // $this->app->register(\Ibrand\DatabaseLogger\ServiceProvider::class); }
was registered, everything was normal.
2. Study the source code
The registration of providers
in config/app.php
is invalid, but in other ServiceProvider# If the registration in ## is valid, it means there is another problem.
registerConfiguredProviders method by studying the
Illuminate\Foundation\Application source code:
config/ in this method providers
content in app.php and
load to
ProviderRepository.
(new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath())) ->load($providers->collapse()->toArray());
$this->getCachedServicesPath(). Through the source code, we found that Laravel determines how to register based on the
bootstrap/cache/services.php file
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 optimize
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, becauseAppServiceProvider is not delayed loading, so the
register method in
AppServiceProvider is executed to register a new one
ServiceProvider will not be delayed loaded either.
ServiceProvider
defer After setting the attribute value,
php artisan clear-compiled and
php artisan optimize need to be executed to update the ServiceProvider cache.
middleware and
route in 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!