門面 - laravel 5.3

weixin_34377065發表於2017-03-11

門面:作為laravel伺服器容器中底層類的“靜態代理”。
門面的載入過程:

  • 如:我們在使用View門面,渲染檢視時(當然可以使用輔助函式view()其實都是一樣的)
use Illuminate\Support\Facades\View;
View::make('','','');

當程式執行到View::make()門面時,就會去載入Illuminate\Support\Facades\View
我們看看Illuminate\Support\Facades\View時如何定義的???

<?php
namespace Illuminate\Support\Facades;
/**
 * @see \Illuminate\View\Factory
 */
class View extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return 'view';
    }
}

沒錯,子定義了一個getFacadeAccessor靜態方法。(該方法的作用是:返回View在伺服器容器中繫結的名稱,便於後面解析)
更多的系統定義的門面都在這裡:

3240400-4ab4c3fa39e3d31e.png

我們知道Illuminate\Support\Facades\View只定義了一個getFacadeAccessor靜態方法,但是View繼承(extends)Facade類(該類是所有門面必須繼承的,它主要是引導門面的作用)
我們知道php的魔術方法,當需要載入的方法不存在時,會去指定__callStatic(args);args傳遞引數;

<?php
namespace Illuminate\Support\Facades;
use Mockery;
use RuntimeException;
use Mockery\MockInterface;
abstract class Facade
{
    /**
     * Handle dynamic, static calls to the object.
     *
     * @param  string  $method
     * @param  array   $args
     * @return mixed
     *
     * @throws \RuntimeException
     */
    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);
    }
/**
     * Get the root object behind the facade.
     *
     * @return mixed
     */
    public static function getFacadeRoot()
    {  
        //> 由於View的getFacadeAccessor覆蓋了該方法,該返回名稱 
        return static::resolveFacadeInstance(static::getFacadeAccessor());
    }
}
/**
     * Resolve the facade root instance from the container.
     *
     * @param  string|object  $name
     * @return mixed
     */
    protected static function resolveFacadeInstance($name)
    {
        if (is_object($name)) {
            return $name;
        }
        //> 如果當前門面被解析過,直接從$resolvedInstance屬性中提取
        if (isset(static::$resolvedInstance[$name])) {
            return static::$resolvedInstance[$name];
        }
        //> 第一次被解析,從伺服器容器中提取,並呼叫指定的方法
        return static::$resolvedInstance[$name] = static::$app[$name];
    }

相關文章