Facades原理
Laravel IOC Container總是bind(singleton)進去類,make出類的例項物件
通過Facades可以解析出類的物件,並呼叫類的方法,其實質也是呼叫了make方法解析出類的物件
- 通過這一行簡單的程式碼,我們沒有use Cache這個類,卻可以使用Cache
// 注意Cache前加\ \Cache::set('czz','18',60); dd(\Cache::get('czz'));
程式碼執行流程解析
1 使用Cache類,實際是呼叫了config/app.php中 aliases陣列中的Illuminate\Support\Facades\Cache;
/**
* Prepend the load method to the auto-loader stack.
*
* @return void
*/
protected function prependToLoaderStack()
{
// 把AliasLoader::load()放入自動載入函式佇列中,並置於佇列頭部
// 呼叫\Cache,實際是執行了這個方法,為Illuminate\Support\Facades\Cache註冊別名Cache
spl_autoload_register([$this, 'load'], true, true);
}
/**
* Load a class alias if it is registered.
*
* @param string $alias
* @return bool|null
*/
public function load($alias)
{
if (static::$facadeNamespace && strpos($alias, static::$facadeNamespace) === 0) {
$this->loadFacade($alias);
return true;
}
if (isset($this->aliases[$alias])) {
// 為Illuminate\Support\Facades\Cache註冊別名Cache
return class_alias($this->aliases[$alias], $alias);
}
}
'Cache' => Illuminate\Support\Facades\Cache::class,
2 進入Illuminate\Support\Facades\Cache類,發現沒有set方法和get方法,呼叫父類的魔術方法__callStatic,從容器中解析出類的例項物件;
- 魔術方法__callStatic
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);
}
- 解析
/**
* Get the root object behind the facade.
*
* @return mixed
*/
public static function getFacadeRoot()
{
// 相當於執行的是return static::resolveFacadeInstance("cache);
return static::resolveFacadeInstance(static::getFacadeAccessor());
}
- 從容器中解析出類的物件
protected static function resolveFacadeInstance($name)
{
// $name = ‘cache’;
if (is_object($name)) {
return $name;
}
if (isset(static::$resolvedInstance[$name])) {
return static::$resolvedInstance[$name];
}
return static::$resolvedInstance[$name] = static::$app[$name];
}
- $app是容器物件,因為實現了ArrayAccess介面,所以,最終呼叫的還是容器的make方法
public function offsetGet($key)
{
// $key = "cache";
return $this->make($key);
}
3 執行物件的方法get或者set..
$instance->$method(...$args)