真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

laravel要用門面的原因是什么

本篇內(nèi)容介紹了“l(fā)aravel要用門面的原因是什么”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)長期為1000多家客戶提供的網(wǎng)站建設(shè)服務(wù),團隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為西山企業(yè)提供專業(yè)的成都網(wǎng)站設(shè)計、網(wǎng)站制作,西山網(wǎng)站改版等技術(shù)服務(wù)。擁有10余年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。

在laravel中,因為門面能夠為應(yīng)用的服務(wù)容器提供一個“靜態(tài)”接口,相比于傳統(tǒng)的靜態(tài)方法,門面提供的“靜態(tài)”接口相當(dāng)于是服務(wù)容器底層類中的一個靜態(tài)代表,能夠提供更加靈活和易于測試的語法,所以在laravel中要用到門面。

本文操作環(huán)境:Windows10系統(tǒng)、Laravel6版、Dell G3電腦。

laravel為什么用門面

Laravel 中的門面總體上還是遵循著門面模式的基本思想的。Laravel 中的門面是為應(yīng)用的服務(wù)容器提供一個【靜態(tài)】接口,相當(dāng)于是服務(wù)容器底層類中的一個【靜態(tài)代表】,能夠提供更加靈活、易于測試、優(yōu)雅的語法。

對于 Laravel 中的門面來說,我們會經(jīng)常使用到,比如說緩存。

Cache::get('key');

再比如我們之前經(jīng)常用的數(shù)據(jù)庫和 redis 。

DB::connection('MySQL2')->table('db_test')->get()->toArray();
 
Redis::connection('default')->client()->get('test')

發(fā)現(xiàn)沒有,門面全是用的靜態(tài)方法。但是你點過去,會發(fā)現(xiàn)這個門面類里面什么東西都沒有呀!

class Cache extends Facade
{
    protected static function getFacadeAccessor()
    {
        return 'cache';
    }
}

在 Facade 類中,別的方法函數(shù)我們先不用看,直接拉到最底下,你會發(fā)現(xiàn)一個魔術(shù)方法,__callStatic() 。

public static function __callStatic($method, $args)
{
    $instance = static::getFacadeRoot();
 
    if (! $instance) {
        throw new RuntimeException('A facade root has not been set.');
    }
 
    return $instance->$method(...$args);
}

__callStatic() 的意思是通過靜態(tài)調(diào)用時如果沒有定義對應(yīng)的方法,就進入到 __callStatic() 方法中,比如我們調(diào)用的 Cache::get() 這個方法,實際上當(dāng)前的 Cache 門面類以及它的父類 Facade 都沒有定義這個方法,那么就直接進入到了 __callStatic() 中。接著,它就通過 getFacadeRoot() 獲取我們當(dāng)前門面的實例對象,然后調(diào)用實例對象中的 get() 方法。

好了,到此為止,其實如果面試的時候有面試官問你 Laravel 中的門面模式是如何實現(xiàn)的時候,你就可以自信地說核心就是這個 __callStatic() 魔術(shù)方法了。那么這個具體的實例對象又是從哪里來的呢?我們繼續(xù)往下看。

實例對象

接下來我們看看 Facade 中的具體實例對象是怎么獲取的。這里我們又要回到服務(wù)容器中。不過還是先從門面入口來看看吧。

在 __callStatic() 方法中,我們會看到調(diào)用了一個 static::getFacadeRoot() 方法來獲得具體的實例對象。

public static function getFacadeRoot()
{
    return static::resolveFacadeInstance(static::getFacadeAccessor());
}

這個方法的內(nèi)容很簡單,就是調(diào)用了另外兩個方法,注意 getFacadeAccessor() 是我們的各個門面子類中實現(xiàn)的,比如例子中就是在 Cache 這個類中實現(xiàn)的。它只是返回一個實例的別名,還記得這個別名是在哪里定義的嗎?我們在服務(wù)容器中看到過,就是 vendor/laravel/framework/src/Illuminate/Foundation/Application.php 中 registerCoreContainerAliases() 方法里面定義的那些。

接下來,我們主要看的就是 static::resolveFacadeInstance() 這個方法。從名字我們可以出,它的意思是 解決門面實例 ,這貨要是不返回一個實例對象那還真對起它的名字了。

protected static function resolveFacadeInstance($name)
{
    if (is_object($name)) {
        return $name;
    }
 
    if (isset(static::$resolvedInstance[$name])) {
        return static::$resolvedInstance[$name];
    }
 
    if (static::$app) {
        return static::$resolvedInstance[$name] = static::$app[$name];
    }
}

第一個判斷,如果傳遞進來的是一個對象,直接返回。第二個判斷,如果當(dāng)前實例數(shù)組中已經(jīng)有了,就不再創(chuàng)建了,類似于一個 享元模式 的效果。注意,靜態(tài)的成員數(shù)組哦!什么意思呢?靜態(tài)的全局共享的,也就是說,你這個實例對象創(chuàng)建之后,其他地方都可以使用,完全的單例狀態(tài)。最后一個判斷,app 也就是我們的服務(wù)容器存在的話,進行服務(wù)容器的操作。

我們先來看下這個 app 屬性是什么時候賦值的。在講服務(wù)提供者時,Kernel 中有一個 bootstrappers 屬性數(shù)組,其中有一個 RegisterFacades 提供者。很明顯,它是用于注冊門面的一個服務(wù)提供者,在這個服務(wù)提供者中,我們會看到這樣的代碼。

public function bootstrap(Application $app)
{
    Facade::clearResolvedInstances();
 
    Facade::setFacadeApplication($app);
 
    AliasLoader::getInstance(array_merge(
        $app->make('config')->get('app.aliases', []),
        $app->make(PackageManifest::class)->aliases()
    ))->register();
}

其中的 Facade::setFacadeApplication() 就是將 服務(wù)容器 的 Application 對象注入到了門面類的靜態(tài)成員變量 app 中。注意,同樣是靜態(tài)的,全局存在的。

然后我們繼續(xù)回到 resolveFacadeInstance() 方法中。

protected static function resolveFacadeInstance($name)
{
    // …………
    // …………
    if (static::$app) {
        return static::$resolvedInstance[$name] = static::$app[$name];
    }
}

這里怎么回事,怎么就通過 static::$app[$name] 就能獲得一個實例對象了呢?別激動,別著急,想想怎么讓一個對象可以進行這樣的數(shù)組操作?我們之前學(xué)過的哦!

就是這個 ArrayAccess 接口,它必須實現(xiàn)的那幾個方法可以讓對象像數(shù)組一樣去使用。

OK,知道原理了,我們來看看是不是這樣,找到 Application 的父類 vendor/laravel/framework/src/Illuminate/Container/Container.php 。

class Container implements ArrayAccess, ContainerContract
{
    // …………
    // …………
    public function offsetGet($key)
    {
        return $this->make($key);
    }
    // …………
    // …………
}

“l(fā)aravel要用門面的原因是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!


當(dāng)前名稱:laravel要用門面的原因是什么
當(dāng)前路徑:http://weahome.cn/article/jjshei.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部