According to the manual tutorial yesterday, I started to write an auth extension. According to the packet independence principle, I do not wantAuth::extend()
This method is written inStart. phpWithout a doubt, I chose to provideregister()
Method. However, this is counterproductive ......
Http://www.zroran.com/it/php/laravel/10.html
Problems Found
When ILoauthserviceproviderWhen writing like this:
public function register(){ // \Auth::extend(‘loauth‘,function($app){});}
Error
Call to undefined method Illuminate\Support\Facades\Auth::extend()
Find the reason
At that time, I was wondering why I suspected auth was not registered? Check and find that the domain name is registered because it can be used in the route;php artisan clear-compiled
Useless. I was puzzled. I even suspected that I accidentally modified the core class and downloaded the laravel package again.
After one night of tossing, I finally got my eyes lockedAuthserviceproviderOf$defer
Attribute.
Based on the manual and comments, we know that$defer
Attribute is used to delay the loading of the service provider. To put it bluntly, it means delayed execution.register()
Method.provides()
Method. For example:
public function provides(){ return array(‘auth‘);}
This isAuthserviceproviderWhen the framework is initialized, the service provider is loaded in sequence.protected $defer=true
Then it will be calledprovides()
Method. The returned array containsService nameIn this way, when we callAuth::METHOD()
Will callregister()
Method.
Identify the crux
The problem arises. Since it is passive delayed loading, that is to say, the auth class should be automatically instantiated when I call the auth class method. Why did I prompt that the method does not exist when I call the method in loauthserviceprovider, but it does in routing.
I guess it is because of a priority issue. When the framework registers loauthserviceprovider: Register (), auth is not marked as delayed loading, which leads to a sequential problem,Any real-time loading service provider cannot call the delayed loading service in the register method..
After research, we can find evidence in the core code.
Illuminate \ Foundation \ providerrepository
Public Function load (Application $ app, array $ providers ){//... omit // we will go ahead and register all of the eagerly loaded providers with the // application so their services can be registered with the application as // A provided service. then we will set the deferred service list on it. foreach ($ manifest ['eager '] as $ provider) {$ app-> Register ($ this-> createprovider ($ app, $ provider ));} // delayed loading mark $ app-> setdeferredservices ($ manifest ['referred']) after the service is loaded instantly;}
Solution
Although the problem is found, it does not mean that the problem is solved. Modifying the core code is not a wise choice, so we can only find a solution in our own package. One solution is as follows:
public function register(){ // $authProvider = new \Illuminate\Auth\AuthServiceProvider($this->app); $authProvider->register(); \Auth::extend(‘loauth‘,function($app){});}
Since auth is not yet registered, we can manually call its register method to register it.
Message
The research framework is also a learning process. Maybe you have a better way.
Talk about laravel container delay loading and Auth Extension