溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

laravel容器延遲加載及auth擴(kuò)展的方法

發(fā)布時(shí)間:2022-03-30 15:38:25 來(lái)源:億速云 閱讀:196 作者:iii 欄目:開(kāi)發(fā)技術(shù)

這篇“l(fā)aravel容器延遲加載及auth擴(kuò)展的方法”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來(lái)看看這篇“l(fā)aravel容器延遲加載及auth擴(kuò)展的方法”文章吧。

發(fā)現(xiàn)問(wèn)題

當(dāng)我在 LoauthServiceProvider 中這樣寫(xiě)的時(shí)候:

復(fù)制代碼 代碼如下:


public function register()
{
    //
    \Auth::extend('loauth',function($app){});
}

報(bào)錯(cuò)

復(fù)制代碼 代碼如下:


Call to undefined method Illuminate\Support\Facades\Auth::extend()

尋找原因

當(dāng)時(shí)就納悶了,找原因,懷疑是Auth沒(méi)注冊(cè)?檢查發(fā)現(xiàn)注冊(cè)了,因?yàn)樵诼酚芍锌梢允褂?;php artisan clear-compiled 沒(méi)用;百思不得其解,甚至懷疑是我不小心修改了核心類(lèi),還重新下載了一次laravel包,問(wèn)題依舊。

折騰了一晚上,最終我把目光鎖定在 AuthServiceProvider 的 $defer 屬性。

根據(jù)手冊(cè)以及注釋?zhuān)覀兊弥?$defer 屬性是用來(lái)延遲加載該服務(wù)提供器,說(shuō)直白點(diǎn)就是延遲執(zhí)行 register() 方法,只需要配合provides()方法即可實(shí)現(xiàn)。舉個(gè)例子:

復(fù)制代碼 代碼如下:


public function provides()
{
    return array('auth');
}

這個(gè)是 AuthServiceProvider 里的方法,當(dāng)框架初始化的時(shí)候,會(huì)依次加載服務(wù)提供器,如果發(fā)現(xiàn)這個(gè)服務(wù)提供器protected $defer=true 那么就會(huì)調(diào)用它的 provides() 方法,其返回的數(shù)組包含需要延遲加載的服務(wù)名稱(chēng),這樣當(dāng)我們?cè)诼酚?、控制器或者其他地方調(diào)用 Auth::METHOD() 的時(shí)候,才會(huì)去調(diào)用提供器的 register() 方法。

確定癥結(jié)

那么問(wèn)題來(lái)了,既然是被動(dòng)延遲加載,也就是說(shuō)當(dāng)我調(diào)用Auth類(lèi)方法時(shí)應(yīng)該會(huì)自動(dòng)實(shí)例化Auth類(lèi)啊,為什么我在LoauthServiceProvider中調(diào)用的時(shí)候卻提示方法不存在,但是在路由中卻可以呢。

我猜測(cè)是因?yàn)閮?yōu)先級(jí)的問(wèn)題,可能在框架注冊(cè) LoauthServiceProvider::register() 的時(shí)候,Auth 還沒(méi)有標(biāo)記為延遲加載,這就造成了一個(gè)先后問(wèn)題,任何即時(shí)加載的服務(wù)提供器都無(wú)法在register方法中調(diào)用延遲加載的服務(wù)。

經(jīng)過(guò)研究,順利在核心代碼中找到證據(jù) Illuminate\Foundation\ProviderRepository

復(fù)制代碼 代碼如下:


public function load(Application $app, array $providers)
{
    //...省略
    // 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));
    }
    //延遲加載標(biāo)記在即時(shí)加載服務(wù)之后
    $app->setDeferredServices($manifest['deferred']);
}

解決之道

雖然發(fā)現(xiàn)了問(wèn)題所在,但并不代表問(wèn)題就解決了,修改核心代碼不是個(gè)明智的選擇,所以只能在我們自己的包里想辦法咯,一個(gè)解決方案如下:

復(fù)制代碼 代碼如下:


public function register()
{
    //
    $authProvider = new \Illuminate\Auth\AuthServiceProvider($this->app);
    $authProvider->register();
    \Auth::extend('loauth',function($app){});
}

既然auth還未注冊(cè),那么我們手動(dòng)調(diào)用它的register方法幫它注冊(cè)。

以上就是關(guān)于“l(fā)aravel容器延遲加載及auth擴(kuò)展的方法”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對(duì)大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI