1.5 - Laravel 5.6 - Alias 别名

通过服务绑定的别名,在解析服务的时候,跟不使用别名的效果一致。别名的作用也是为了同时支持全类型的服务绑定名称以及简短的服务绑定名称考虑的。

什么东西,看不懂

通俗的讲,小红学名也就是大名叫 小红。别名alias也就是小名,可以是小宝红红等。都是一个人。

举例:

假如我们想要创建 auth 服务,我们既可以这样写:

$this->app->make('auth')

又可以写成:

$this->app->make('\Illuminate\Auth\AuthManager::class')

还可以写成

$this->app->make('\Illuminate\Contracts\Auth\Factory::class')

后面两个服务的名字都是 auth 的别名,使用别名和使用 auth 的效果是相同的。

auth是我们的大名。

加载别名:

1. 通过调用Container中的alias方法,我们看下源代码

这里有两个数组:aliases和abstractAliases,他们保存一样的数据,但是键值对相反。

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

laravel在初始化的时候给系统的核心对象加了别名:对应的方法是registerCoreContainerAliases()

public function registerCoreContainerAliases()
{
    foreach ([
    ......
    'auth' => [\Illuminate\Auth\AuthManager::class, \Illuminate\Contracts\Auth\Factory::class],

......
        ] as $key => $aliases) {
        foreach ($aliases as $alias) {
        $this->alias($key, $alias);
    }
}

遍历别名数组,然后调用alias方法,把数据加载到指定数组中存储。

加载别名后,容器的 aliases 和 abstractAliases 数组数据就变成了这样,键值和值 正好相反存储:

两个数组的作用分别是:

1.aliases 通过小名找到大名

2.abstractAliases 通过大名找到所有的小名

$aliases = [
    ...
    'Illuminate\Auth\AuthManager' = "auth"
    'Illuminate\Contracts\Auth\Factory' = "auth"
    ...
]

$abstractAliases = [
    auth = [
    "Illuminate\Auth\AuthManager"
    "Illuminate\Contracts\Auth\Factory"
    ]
...
]

别名的获取

直接看源码getAlias

1.看看有没有对应的$abstruct的别名。如果没有就返回当前$abstruct.

2.如果发现别名和$abstruct一样,抛出异常,别名不能和自己一样。

3.进一步递归,查看这个别名是否还有别名的别名。

从这点我们可以知道,别名返回的是**最终的那个大名叫什么** 我们这里的这个例子最后的大名就是auth


public function getAlias($abstract)
{
    if (! isset($this->aliases[$abstract])) {
        return $abstract;
    }
    if ($this->aliases[$abstract] === $abstract) {
        throw new LogicException("[{$abstract}] is aliased to itself.");
    }

    return $this->getAlias($this->aliases[$abstract]);
}

总结

别名alias数据会存储到两个数组中:
1.abstractAliases
2.abstructs

1.搜了源码:第一个数组abstractAliases用来处理上下文绑定时,寻找接口对应的类对象。就是先找到某个abstract(大名,这里是auth)所有的别名(通常是接口),然后依次去上下文绑定数组中寻找是否存在对应接口的·实体类对象·

2.第二个数组abstructs则在很多情况下使用,主要作用就是通过小名寻找真正的大名

现在看来别名的主要作用是把一些接口和实体类对象建立关系。次要作用是简化实体类命名。每次调用全路径挺恶心的。

后面laravel 会通过serviceprovider 把·大名·和·实体类·绑定
所有基本结构是这样的:

别名-红红(alias)->大名-小红(abstruct)->绑定小红这个人(object)

总之就是取名字用的 没什么大不了。


已测示例

我们用别名alias_money重新命名了Money::class

别名先找到‘money’再去找到Money::class`


class ExampleTest extends TestCase
{
    public function testClosure()
    {
        app()->bind('money', Money::class);
        app()->alias('money','alias_money');
        $boss= app()->make('alias_money');
        $output = $boss->getAmount();
        $this->assertEquals($output, 100);
    }
}

class Money
{
    public function getAmount(){
        return 100;
    }
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 1

真好,看了这文章更蒙了。

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!