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');
它甚至第三次将其存储在别名数组的容器中:
"App\Util\Portal\UrlGenerator" => "url"
我的问题:
为什么 Laravel 将它们全部存储两个或三个而不覆盖它们?存储具体类应该足够了。
但为什么 Laravel 将这三个都存储起来呢?当我现在使用 App::make('url') 时,laravel 如何判断要解析哪一个? Laravel 现在有三种可供选择,一种接口和两种实现。
在睡了一晚并深入研究代码之后(尚未在代码中 100% 验证),最有可能的是:
“别名”
以各种方式/方法使用:
- 它可以表示 Facade 的别名(如 FacadeClass 的 URL)。这是完全不同的东西(!?)
- 它可能意味着将所谓的“抽象”(术语/字符串)(如“url”)映射到“别名”,在 Laravel 术语中,“别名”是一个类或(!)接口。
别名(如上面的方法所做的那样)并不需要直接对绑定执行任何操作。
“捆绑”
Laravel Container 在其 Container 类中有两个属性,名为$aliases
and $bindings.
绑定将“抽象”的真实绑定保存到要实例化的具体类!
因此,每个别名(如上所述)还需要(!)从要实例化的“抽象”具体类中获得相应的绑定(!)。
结论
实际上,如上所述,键/抽象“url”有三个别名(具体类和接口)。但他们有
与实例化过程无关。为了使别名在那里工作,还需要有一个真正的绑定!
因此,实际上“容器别名”允许您访问与其他类或接口名称的现有绑定。
- 如果你打电话
Container::make()
对于任何别名,laravel 都会尝试将它们解析为“抽象”(此处为“url”)。
- 然后在第二步中,尝试根据绑定解析这个抽象“url”(这是完全不同的东西)。
- 如果未找到别名的绑定,则会引发错误。
因此,您可以拥有任意数量的别名,但只能有一个绑定,并且您必须拥有该单一绑定(另外!)。
(有趣的是,如果将别名映射到与绑定相同的类,则似乎会导致递归错误。但这也可能是一个
xdebug 问题)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)