You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<?phpnamespaceIlluminate\Support\Facades;
useIlluminate\Contracts\Auth\Access\GateasGateContract;
class Gate extends Facade
{
/** * Get the registered name of the component. * * @return string */protectedstaticfunctiongetFacadeAccessor()
{
return GateContract::class;
}
}
一般的,
Facade
类都继承于Illuminate\Support\Facades\Facade
。比如
Illuminate\Support\Facades\Gate
这个门面:代码中我们只需要留意
getFacadeAccessor
方法是在Illuminate\Support\Facades\Gate
中定义的就好了。我们来分析
Illuminate\Support\Facades\Facade
:魔术方法 part 1
首先我们来看末尾的
__callStatic
方法:laravel/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php
Lines 206 to 224 in ca57c28
还记得 Facade 类我们是怎么调用的吗?
静态调用!比如
Gate::allows()
。因为在 Facade 类中定义了
__callStatic
魔术方法,所以只要静态调用了里面没有提供的方法,都会走到魔术方法里面。这个魔术方法内部有一个取出实例的逻辑:
代码位于
laravel/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php
Lines 123 to 131 in ca57c28
前面,我们留意了
static::getFacadeAccessor()
是位于Illuminate\Support\Facades\Gate
中的,而static::getFacadeAccessor()
运行后作为参数给了static::resolveFacadeInstance()
,后者实现为laravel/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php
Lines 145 to 162 in ca57c28
而
static::$app
就是容器对象laravel/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php
Lines 11 to 16 in ca57c28
这句
laravel/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php
Line 161 in ca57c28
尝试从容器对象
数组取
操作,就是调用了make
laravel/vendor/laravel/framework/src/Illuminate/Container/Container.php
Lines 1208 to 1211 in ca57c28
就是从容器取出对象。
总结
getFacadeRoot
的逻辑大概为static::getFacadeAccessor()
返回是否对象,如果对象则直接使用。Facade::$resolvedInstance
数组中尝试根据$name
取出对象,避免多次调用时,每次都取。Illuminate\Foundation\Application
容器取出对象。魔术方法 part 2
拿到
$instance
后,先验证$instance
是否为空。如果是就报错A facade root has not been set.
。laravel/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php
Lines 219 to 221 in ca57c28
最后,直接把方法和参数穿透到背后的
$instance
去执行。laravel/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php
Line 223 in ca57c28
Laravel 有很多 facade 门面,背后穿透的不只一个类(譬如
DB
、View
、Session
),这是怎么回事呢?请看 15. Laravel 神奇的 Manager 类
The text was updated successfully, but these errors were encountered: