保护私人版权,尊重他人版权。转载请注明出处并附带页面链接
Facade 是什么
Facade 其实是一个容器中类的静态代理,他可以让你以静态的方式来调用存放在容器中任何对象的任何方法。举个例子:
1 | use Illuminate\Support\Facades\Cache; |
实际上,Cache 类并没有一个 get 静态方法,但是却可以被调用,这就是 Facade 的静态代理功能
门面工作原理
门面就是一个为容器中对象提供访问方式的类。该机制原理由 Facade 类实现。框架自带的门面,以及我们创建的自定义门面,都会继承自 Illuminate\Support\Facades\Facade 基类。
门面类只需要实现一个方法:getFacadeAccessor。正是 getFacadeAccessor 方法定义了从容器中解析什么,然后 Facade 基类使用魔术方法 __callStatic() 从你的门面中调用解析对象。
门面类调用静待方法解析流程:
1 | public static function __callStatic($method, $args) |
getFacadeRoot方法解析出门面的对象,getFacadeAccessor静态方法必须由继承Facade 基类的门面类实现,如果不重写该方法会直接抛出异常
1 | public static function getFacadeRoot() |
解析门面对象方法:如果getFacadeAccessor方法返回的是一个对象,则直接返回该对象,否则从$app中获取该名称对应的对象,再将该对象存入静态变量中,形成单例
1 | protected static function resolveFacadeInstance($name) |
得到对象后,就是直接通过对象来调用方法了
1 | $instance->$method(...$args); |
注意:如果getFacadeAccessor返回的是字符串,则需要服务容器$app能够解析出相应的对象,即需要该字符串有相关的服务容器绑定;