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:
- 它可以表示 Facade 的别名(例如 URL 到 FacadeClass)。这是完全不同的东西(!?)
- 这可能意味着将所谓的 "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 或接口名称的现有绑定。
- 如果您使用任何别名调用
Container::make()
,laravel 将尝试将它们解析为 "abstract"(此处为 "url")。
- 然后在第二步中,这个抽象 "url" 然后尝试针对绑定进行解析(这是完全不同的东西)。
- 如果找不到别名的绑定,则会抛出错误。
所以你可以有任意数量的别名,但只有一个绑定,你必须有一个绑定(另外!)。
(有趣的是,如果您将别名映射到与绑定相同的 class,它似乎以递归错误结束。但这也可能是一个
xdebug 问题)。
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:
- 它可以表示 Facade 的别名(例如 URL 到 FacadeClass)。这是完全不同的东西(!?)
- 这可能意味着将所谓的 "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 或接口名称的现有绑定。
- 如果您使用任何别名调用
Container::make()
,laravel 将尝试将它们解析为 "abstract"(此处为 "url")。 - 然后在第二步中,这个抽象 "url" 然后尝试针对绑定进行解析(这是完全不同的东西)。
- 如果找不到别名的绑定,则会抛出错误。
所以你可以有任意数量的别名,但只有一个绑定,你必须有一个绑定(另外!)。
(有趣的是,如果您将别名映射到与绑定相同的 class,它似乎以递归错误结束。但这也可能是一个 xdebug 问题)。