Skip to content

Latest commit

 

History

History
88 lines (73 loc) · 2.24 KB

realtime-facade.md

File metadata and controls

88 lines (73 loc) · 2.24 KB

实时Facade

实时Facade免去了要写一个Facade类的过程,只需要在导入的名称前面加上Facades就可以了,假如你在服务容器中有一个名为 App\Contracts\Publisher的绑定,那么你只需要导入Facades\App\Contracts\Publisher,这样,Publisher就 成了一个Facade。

AliasLoaderload方法里有这样一段逻辑

//src/Illuminate/Foundation/AliasLoader.php

/**
 * 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])) {
        return class_alias($this->aliases[$alias], $alias);
    }
}

关注的重点是第一个分支,进入这个分支的条件就是,导入的名称是以Facades开头的。

//src/Illuminate/Foundation/AliasLoader.php

/**
 * Load a real-time facade for the given alias.
 *
 * @param  string  $alias
 * @return void
 */
protected function loadFacade($alias)
{
    require $this->ensureFacadeExists($alias);
}

/**
 * Ensure that the given alias has an existing real-time facade class.
 *
 * @param  string  $alias
 * @return string
 */
protected function ensureFacadeExists($alias)
{
    if (file_exists($path = storage_path('framework/cache/facade-'.sha1($alias).'.php'))) {
        return $path;
    }

    file_put_contents($path, $this->formatFacadeStub(
        $alias, file_get_contents(__DIR__.'/stubs/facade.stub')
    ));

    return $path;
}

/**
 * Format the facade stub with the proper namespace and class.
 *
 * @param  string  $alias
 * @param  string  $stub
 * @return string
 */
protected function formatFacadeStub($alias, $stub)
{
    $replacements = [
        str_replace('/', '\\', dirname(str_replace('\\', '/', $alias))),
        class_basename($alias),
        substr($alias, strlen(static::$facadeNamespace)),
    ];

    return str_replace(
        ['DummyNamespace', 'DummyClass', 'DummyTarget'], $replacements, $stub
    );
}

从上面三个方法可以看出来,实时Facade的实现就是通过分析导入的Facade的名称,将它转化成Facade类定义文件,然后缓存起来。