Laravel 执行流程(三)之 探索 Application 构造函数

备注:纯手打的学习笔记,如有错误之处请指正,谢谢。希望大家学的开心!

说明:本来应该是说 Container 类(下)的,不过经过学习,直接看这个类实在不好理解,一会是绑定,一会共享实例,真心不知道说的什么....还是先从程序的入口处,顺藤摸瓜,用到的时候再结合上下文理解,比较容易消化,希望理解,抱歉!

  • OK,从入口地址 public/index.php 看到如下代码:

file

注释很有趣,翻译凑合看吧。
则现在我们打开 bootstarp/app.php 文件,因为这是 $app 这个玩意儿的出生地。

file

咱们就从在这里摸索一下构造函数里面发生了什么,则打开 Application.php 文件。

再次给各位学友提示一次:怎么找具体文件我就略过了,前面都具体说过,一般看见命名空间,基本就可以找到对应的文件路径。

如现在打开的 Application.php 是位于 vendor/laravel/framework/src/Illuminate/Foundation/Application.php,而命名空间是 Illuminate\Foundation

Application类的构造函数截图如下:

file

因为代码量真的很多,如果每一点都要说,不仅会看得云里雾里,还不一定能理解,所以,我这里以总结的方式概述,特别值得学习的地方再单独提出来说。

一、registerBaseBindings()

注册一些基本的绑定到容器中。

简单点说,此方法内部进行3次赋值,赋值后的变量及变量内容形式如下:

Container::$instance = $this

$this->instances['app'] = $this

$this->instances['Illuminate\Container\Container'] = $this

变量名具体含义:

$this,也就是 Application 类。

Container::$instance,之前说过 Application 是 Container 的子类,而 $instance 静态变量是在 Container 类中已经定义好的,截图示:

file

$this->instances,也是在 Container 中定义的,含义为存放容器的共享实例,截图示:

file

你可以在 registerBaseBindings 方法的最后面打印如下3个变量进行检测,得到的都是 application object,

file

到此,所谓的基本绑定结束,还是云里雾里的,英文不好只能看代码了,反正你记住父类的2个成员属性已经得到了 application 对象。

二、registerBaseServiceProviders()

注册所有的基础服务提供商。

好吧,第二章提过的 ioc 容器=地基,开始买材料准备施工,找几个最基础的供应商商来进行合作,搞水泥的啊,砌砖的啊,以后有更多的需求,根据自己的需求在去找供应商谈。Laravel 刚开始注册了2个提供商,一个事件,一个是路由。

file

我们先意淫一下大概的意思,找到了供应商,准备合作签合同( register ),先和搞水泥的签( event ),在和砌砖的签( routing ),和谁签?I'm the boss( $this )。
既然我是老板,合同条款肯定得看清楚了,咱们去看看合同先( register方法 )
嗯!合同说的很清楚,首先确定我和供应商是否签过合同了,签过了( getProvider() 来判断)就滚蛋,浪费时间;虽然我是老板,但不是法人,你打个电话叫他过来,名字叫狗蛋(resolveProviderClass 方法,如果 $provider 为 string 类型,则根据提供的类名帮供应商实例化并 return),如图

file

OK,差不多,狗蛋把字一签( $provider->register() ),供应商算是正式入驻施工团队了,当然了,合同还说明以后要是有其他要改的地方,直接填一份声明即可,$optionsregister方法 的第二个参数。

file

既然签了合同,就要如公司档案,狗蛋屁颠屁颠的跑去档案室了($this->markAsRegistered($provider) )标记为已注册;好,大功告成( return $provider )。

至此,合同也签好了,其实还有很多地方没提到,提到的话就跑题了。

三、registerCoreContainerAliases()

注册核心容器的别名。

嗯,这个简单的多,还有啥好说的呢,定义容器里面一些核心类的别名,有兴趣直接去看这个方法就行。图示:

file

当然了最后是存放在 $aliases 这个数组里面哟,在 container 定义的成员属性。

四、setBasePath()

设置基本路径。

这个更简单了,这就是前面说 $app 出生地的地方,传了一个路径参数,如图:

file

就是把参数赋值给 $basePath 成员属性,值得一提的是 bindPathsInContainer() 方法,很灵活,在容器内绑定路径,怎么个绑定法?图示:

file

这里用 basePath 举例说明,先是在 $this->instances[‘path’] 单元绑定一个当前 laravel 根目录路径的这样一个字符串,接着把常用的,如基本路径,配置路径,数据库路径等 key 名称组成一个数组 foreach 循环,然后关键来了,把 foreach 里面的代码简易化就是: $this->instance(path.base,$this->basePath()),而 basePath 方法也是早就定义好的,代码一句话:

file

这样一来,刚才赋值的 basePath 成员属性返回即可。还有一些 databasePath,langPath,publicPath 都可以去看看,挺有趣。

至此,$app 终于生出来了,绑定了 application 对象,和2个供应商签了合同,给一些核心类起了别名,配置了 laravel 根目录地址,下一章继续深入其他有趣的地方,欢迎关注!

下一章:Laravel 执行流程(四)之 认识 Bind

本帖已被设为精华帖!
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 5
(= ̄ω ̄=)··· 暂无内容!

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