每一個facade 對應一個服務提供者類。如何從facade 解析出該類呢?
以
Illuminate\Support\Facades\Route爲例。該類內容如下,只有一個方法
class Route extends Facade { /** * Get the registered name of the component. * * @return string */ protected static function getFacadeAccessor() { return 'router'; } }查看基類facade中有一個魔術方法,通過調用魔術方法來解析真正調用的類。如下
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); }於是查看getFacadeRoot 函數
public static function getFacadeRoot() { return static::resolveFacadeInstance(static::getFacadeAccessor()); }其中
static::getFacadeAccessor()這個地方比較迷惑了。因爲基類中也有了getFacadeAccessor函數,到底是調用子類的方法,還是該類自己的方法。於是引出另一個問題static 與self 的區別
經探究發現static 調用的是子類中的方法(如果子類中含有與父類中相同的方法),self 調用的是本類中的方法。於是代碼變成
return static::resolveFacadeInstance('
router');然後查看這個函數resolveFacadeInstance,發現第一次調用類是從綁定的類中獲取,第二次從解析過的靜態變量中獲取。
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]; }所以調用facade接口中的方法,其實是調用綁定類的方法。