Laravel 之道第 12 章:注册门面 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区

[Laravel 之道第 12 章:注册门面 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区]

导语

这一章,我们说一下 Laravel 引导程序之门面的注册,其实质是:执行 Illuminate\Foundation\Bootstrap\RegisterFacades 类中的 bootstrap 方法。

[file

](https://lccdn.phphub.org/uploads/images/201809/29/27709/S1idWMislp.png?imageView2/2/w/1240/h/0)

bootstrap 方法

不废话,直接贴 RegisterFacades 类的 bootstrap 方法

public function bootstrap(Application $app)
{
    Facade::clearResolvedInstances();

    Facade::setFacadeApplication($app);

    AliasLoader::getInstance(array_merge(
        $app->make('config')->get('app.aliases', []),
        $app->make(PackageManifest::class)->aliases()
    ))->register();
}
  • 首先,这段代码:Facade::clearResolvedInstances();

    指,清理所有门面公共父类 Illuminate\Support\Facades\Facade 保存的实例缓存。

    其本质,我们看这段代码

    public static function clearResolvedInstances()
    {
      static::$resolvedInstance = [];
    }

    明白了吧,就是将静态属性 $resolvedInstance 赋值为空数组,即为清空实例缓存

  • 其次,这段代码:Facade::setFacadeApplication($app);,门面注册的核心呀。。。

    我记得刚刚接触 Laravel 的时候,想使用 Redis,官方文档说,用 Illuminate\Support\Facades\Redis 类。我打开 Illuminate\Support\Facades\Redis,一直追踪到其父类,最后卡在下面这个方法上

    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];
    }

    最后一行,有个 static::$app[$name],当时就是不知道 static::$app 怎么给的值,现在终于找到了。。。

    我们看一下这行代码 Facade::setFacadeApplication($app); 干了什么吧

    public static function setFacadeApplication($app)
    {
      static::$app = $app;
    }

    看到了吧,static::$app 就是在这里赋的值。

  • 最后,有个小难点,也算是核心吧,就是注册类的别名

    AliasLoader::getInstance(array_merge(
      $app->make('config')->get('app.aliases', []),
      $app->make(PackageManifest::class)->aliases()
    ))->register();

    这个就是调用 AliasLoader 类的静态方法 getInstance,以 $app->make('config')->get('app.aliases', [])$app->make(PackageManifest::class)->aliases() 合并后的数组为参数,取返回值,这个返回值是对象,再调用这个对象的 register 方法。

    关于参数,$app->make('config')->get('app.aliases', []) 是有用的,取得就是 app.php 配置文件中的 aliases 数组;$app->make(PackageManifest::class)->aliases() 返回的空数组,不用理会

    1、我们看一下 AliasLoader 类的 getInstance 方法

    public static function getInstance(array $aliases = [])
    {
      if (is_null(static::$instance)) {
          return static::$instance = new static($aliases);
      }
    
      $aliases = array_merge(static::$instance->getAliases(), $aliases);
    
      static::$instance->setAliases($aliases);
    
      return static::$instance;
    }

    再来张截图,我们看一下参数 $aliases 长什么样?

    [file

    ](https://lccdn.phphub.org/uploads/images/201809/29/27709/Upn7PsEpzc.png?imageView2/2/w/1240/h/0)

    • 首先,是单例模式的经典判断,如果 static::$instancenull 则实例化自身,否则跳过
实例化自身,要调用 构造函数的,我们看看构造函数

```php
private function __construct($aliases)
{
    $this->aliases = $aliases;
}
```

简单,就是一个 `$aliases` 数组的赋值

*   其次,由于第一次执行,`static::$instance` 一定为 `null` ,所以,直接 `return` 自身实例对象

### 2、我们看一下 `AliasLoader` 类对象的 `register` 方法

```php
public function register()
{
  if (! $this->registered) {
      $this->prependToLoaderStack();

      $this->registered = true;
  }
}
```

*   首先,判断是否注册过,由于第一次执行,所以未注册过,执行 if 里面的代码
*   其次,我们来看一下 `$this->prependToLoaderStack();` 干了什么吧

```php
protected function prependToLoaderStack()
{
    spl_autoload_register([$this, 'load'], true, true);
}
```

看到没,类的自动加载方法又新增一个成员,他是 `AliasLoader` 类对象的 `load` 方法。并优先执行,所以以后自动加载类,会先执行这里的 `load` 方法,然后执行 Composer 注册的自动加载方法

也就是说,以后 Laravel 容器 `make` 一个 `Redis` 会先加载 `Illuminate\Support\Facades\Redis::class` 类,不信,你看 app.php 配置文件 aliases 数组中键为 `Redis` 的值是什么吧。

因此说,我们在使用 `Illuminate\Support\Facades\Redis` Redis 门面的时候可以简化 use ,如下

```php
<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Redis;  // 这里就是简化

class UserController extends Controller
{
    /**
     * 显示给定用户的配置文件。
     *
     * @param  int  $id
     * @return Response
     */
    public function showProfile($id)
    {
        $user = Redis::get('user:profile:'.$id);

        return view('user.profile', ['user' => $user]);
    }
}
```

laravel framework php

我们是一群被时空压迫的孩子。 ---- 爱因斯坦


Original url: Access

Created at: 2018-10-10 14:28:10

Category: default

Tags: none

请先后发表评论
  • 最新评论
  • 总共0条评论