31

Laravel 中Facade门面是怎么实现?有没有其他实现方式?

 4 years ago
source link: https://www.tuicool.com/articles/eIvA3y2
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Laravel 中Facade门面的实现

Route::get('/', function () {
    return view('welcome');
});

在laravel中的路由文件 routes/web.php 有这么一段代码,用于配置路由。这里 Route 就是用 Facade 实现类方法 get 的静态调用。

Laravel中的Facade解决什么问题?

在php中,很多情况都需要使用一个容器获取到所有的对象,然后再调用改对象的方法,这样在编写代码的时候就会看到很长的一个调用链。例如: 在Yii2中,几乎所有的系统类都是在app容器当中,对这些系统类进行操作都需要执行 Yii::$app->route 获取到类实例,然后在执行方法 Yii::$app->route->get() 。但是如果用Facade实现之后的调用就是 Route::get() 。这样的写法是的代码更加简洁。

Laravel中Facade是怎么实现的?

思路是通过 __callStatic 魔术方法将方法调用代理到实际的对象方法中去。

rIz6Z3z.jpg!web

class Route extends Facade{
    public static function getFacadeAccessor(){
        return 'router';
    }
}

根据每个 Facade 中提供的 getFacadeAccessor 返回实际的对象类名,获取类对象。每个类对象一旦创建,就放在一个静态数组中,因此在一次请求中最多只会被创建一次。

有没有其他的实现方式?

从上面的代码可以看到,其实核心就是一个静态代理的功能。那么有没有其他的实现方式了呢?

IrmuMjr.jpg!web

class Route extends Facade{

}

可以看出,上面的方式也能够实现静态代理,类似于Facade的功能。都是通过魔术方法实现。作用上,都简化了代码编写。

两种不同实现方式的区别

第二种实现方式有一个很大的缺点,那就是必须继承 Facade 类。PHP本身只能继承一个类,所以第二种实现方式对于一些需要继承其他类的对象是不适合的。

Laravel的实现方式,对类本身没有束缚,任何类对象都能够通过创建一个Facade对象实现静态代理。有很大的灵活性。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK