Laravel Facade

  

Facade是容器中的类的静态代理,可以调用容器中任何对象的任何方法。

Route::get(‘/cache’, function(){

        return Cache::get(‘key’);

});

要使用Facade,首先需要继承‘Illuminate\Support\Facades\Facade’类并且实现一个抽象方法‘getFacadeAccessor’。

use Illuminate\Support\Facades\Facade;

class Cache extends

Facade

{

    /**

    *获取组件注册名称

    *

    * @return string

    */

    protected static function getFacadeAccessor() {

        return 'cache';

    }

}

‘getFacadeAccessor’ 这个方法只要返回一个容器绑定类的名字即可,当然也可以直接返回一个类如:

use

Illuminate\Support\Facades\Facade;

use Cache;

class Cache extends

Facade

{

    /**

    *获取组件注册名称

    *

    * @return string

    */

    protected static function getFacadeAccessor() {

        return new Cache;

    }

}

Facade的核心是使用了‘__callStatic’这个魔术方法,使用了这个方法之后,即可直接调用Cache中的get方法,尽管这个方法在Cache类中并不存在。

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);    //调用方法

}

然后以下的在Facade中的方法可以从容器中解析出对象:

public static function getFacadeRoot(){

    return static::resolveFacadeInstance(static::getFacadeAccessor());

}

protected static function getFacadeAccessor(){

    throw new RuntimeException('Facade does not implement getFacadeAccessor

    method.');

}

protected static function resolveFacadeInstance($name){

    if (is_object($name)) {

        return $name;

    }

    if (isset(static::$resolvedInstance[$name])) { 

        return static::$resolvedInstance[$name];

    }

    return static::$resolvedInstance[$name] = static::$app[$name];

}

其中的'getFacadeAccessor'这个方法必须被重写,否者就会抛出异常。然后在'resolveFacadeInstance'这个方法中会先判断是否是一个对象,如果是的话就直接返回。所以上文说的'getFacadeAccessor'这个方法直接返回一个对象也是可以的,奥秘就在这。

然后会去判断需要解析的对象是否已经解析过了,如果解析过了就直接返回,否则会从容器中去解析再返回,这样不仅仅实现了单例,而且还可以提升性能。

得到对象后,就是直接通过对象来调用方法了。

posted @ 2019-05-05 14:46  Victor!!!!  阅读(240)  评论(0编辑  收藏  举报