Laravel-核心:为什么Laravel多次存储别名?

Laravel-Core: Why does Laravel store Aliases multiple times?

Laravel 在其核心 Application.php 中注册了很多默认实现,如下所示:

'url' => ['Illuminate\Routing\UrlGenerator', 'Illuminate\Contracts\Routing\UrlGenerator'],

实际上会调用下面的方法两次

public function alias($abstract, $alias)
    {
        $this->aliases[$alias] = $abstract;
    }

导致 Container->aliases 中的以下值:

"Illuminate\Routing\UrlGenerator" => "url"
"Illuminate\Contracts\Routing\UrlGenerator" => "url"

如果我稍后打电话: $this->app->alias('url', 'App\Util\Portal\UrlGenerator'); 它甚至第三次将它存储在 Container im 别名数组中:

"App\Util\Portal\UrlGenerator" => "url" 

我的问题:

为什么 laravel 将它们全部存储两个或三个而不覆盖它们?存混凝土应该够了class。 但是为什么 laravel 将它们全部存储三个呢?当我现在使用 App::make('url') 时,laravel 如何判断要解决哪个问题? Laravel 现在有三个可供选择,一个接口和两个实现。

经过一个晚上的沉睡并在代码中挖掘更多内容(还不能在代码中进行 100% 验证)它最有可能是这样的:

"Aliasing"

用于各种ways/methods:

  1. 它可以表示 Facade 的别名(例如 URL 到 FacadeClass)。这是完全不同的东西(!?)
  2. 这可能意味着将所谓的 "abstract" (term/string) 如 "url" 映射到 "alias",在 laravel 术语中就是 class 或 (!) 界面。 别名(如上述方法所做的那样)不必直接与绑定做任何事情。

"Binding"

Laravel Container 在其 Container class 中有两个属性名为 $aliases$bindings. Bindings 持有 "abstract" 到具体 class实例化! 因此,每个别名(如上所述)也需要(!)具有来自 "abstract" 的相应绑定(!)要实例化的具体 class。

结论

实际上,如上所述,key/abstract "url" 有三个别名(具体 classes 和接口)。但他们有 与实例化过程无关。为了使别名在那里工作,另外还需要一个真正的绑定!

因此实际上 "Container Aliases" 允许您访问与其他 classses 或接口名称的现有绑定。

  1. 如果您使用任何别名调用 Container::make(),laravel 将尝试将它们解析为 "abstract"(此处为 "url")。
  2. 然后在第二步中,这个抽象 "url" 然后尝试针对绑定进行解析(这是完全不同的东西)。
  3. 如果找不到别名的绑定,则会抛出错误。

所以你可以有任意数量的别名,但只有一个绑定,你必须有一个绑定(另外!)。

(有趣的是,如果您将别名映射到与绑定相同的 class,它似乎以递归错误结束。但这也可能是一个 xdebug 问题)。