Solutions to problems encountered when setting up lazy loading during Laravel Service Provider development

小云云
Release: 2023-03-19 08:08:01
Original
1871 people have browsed it

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];
    }
}
Copy after login

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);
    }
Copy after login

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.

Find the

registerConfiguredProviders method by studying the Illuminate\Foundation\Application source code:

Laravel reads

config/ in this method providers content in app.php and load to ProviderRepository.

(new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath()))
                    ->load($providers->collapse()->toArray());
Copy after login
The key point is

$this->getCachedServicesPath(). Through the source code, we found that Laravel determines how to register based on the bootstrap/cache/services.php fileServiceProvider.

At this time, I thought of the reason why the previously commented

//protected $defer = true; code was still invalid.

So in order for the commented

//protected $defer = true; to be effective, the code needs to be executed.

php artisan clear-compiled 
php artisan optimize
Copy after login
After 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 defer attribute value, you need to execute php artisan clear-compiled and php artisan optimize to update the ServiceProvider cache.

3. Why is registration in AppServiceProvider valid?

It is very simple, because

AppServiceProvider is not delayed loading, so the register method in AppServiceProvider is executed to register a new oneServiceProvider will not be delayed loaded either.

Summary

  1. Use lazy loading with caution

    ServiceProvider

  2. Change

    defer After setting the attribute value, php artisan clear-compiled and php artisan optimize need to be executed to update the ServiceProvider cache.

  3. It is strictly prohibited to register

    middleware and route in lazy-loaded ServiceProvider.

Related recommendations:


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!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template