Laravel 执行流程(六)之 启动 kernel

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

辛苦分享,能赞的就赞一个吧,也欢迎大家交流互动

前两章初步认识了 bindmake 使我们明白生成一个实例的步骤,接下来,我们要认识 kernel,这是与用户交互的关键,咱们打开入口文件截图如下:

file

咱们根据这行代码和这个参数,具体来捋一捋 $kernel 是如何生成的,也当复习。

$app 这个不用解释即 application 类,之前说的 make 方法是位于 container 类中,其实 application 类中也有 make 方法,截图如下:

file

我们现在还不知道具体的用意在哪,不过我们看见了内部调用了父类( container )的 make 方法,所以执行过程是先通过子类的 make 调用到父类的 make ,根据参数咱们继续往下看,这里只传了一个Illuminate\Contracts\Http\Kernel 参数,所以 $parameters 可以无视了。

在继续分析父类 make 方法之前,我们要知道,在 bootstrap/app.php 里进行了3次 singleton 操作, singleton 前面也说过,也就是调用 bind 方法,截图如下:

file

我们看见第一个 singleton 一目了然,对应了我们今天要说的类,不过后面多了一个参数(app\Http\Kernel ),这个参数原型名字是 $concrete ,即具体物。

了解以上这些,我们才正式分析父类的 make 方法:

Make 方法前一章单独说过了,所以略过没有执行到的代码。

这里我们知道,Illuminate\Contracts\Http\Kernel 还没有生成实例,只是绑定了而已,说到绑定,不知道大家还记得 bind 方法是怎么执行的吗?其中有一步是判断如果 $concrete 这个参数不是一个闭包的,则调用 getClosure 方法来强制生成一个闭包给 $concrete ,截图如下:

file

这里注意,$method 最终得到 make,3元运算比较了2个参数,我们知道参数不一样,所以取后者,注释部分是我调试的记录,大家可参照测试。咱们把 getClosure 先截图记录,一会用到方便看,咱们继续看 container 类的 make 方法。

file

我们知道这个方法只能返回2种参数,一个是闭包对象,一个字符参数,这里 $concrete 自然是得到一个闭包对象,因为已经绑定过了。

接着直接执行了 build 方法,咱们看 build 方法内的关键代码:

file

嗯看到这里,我们上一章也说过,一个闭包的调用,这里需要跳回 getClosure 继续分析了:

$concrete($this, $parameters) 这里是传了一个 this 参数,即 application 类,所以 $c=application 类,那结合刚才说 getClosure 方法,这里闭包内部应该是执行一个 $c->make($concrete) 逻辑,注意参数 $concrete 是第一次传的 app\Http\Kernel 字符串;那更直接一点,代码其实是这样 application->make(‘app\Http\Kernel’)

make(‘Illuminate\Contracts\Http\Kernel’) 又转换到 make(‘app\Http\Kernel’) ,我们现在只需要知道这个顺序。

好,那再一次去看 make 如何实例化这个 app\Http\Kernel 类的,这次应该有不同的收获哟。

再次执行到 getConcrete 方法,我们说了要么是返回一个闭包对象,要么就是一个字符串,前面都是返回的闭包,而这次呢?转到 getConcrete 相关代码:

file

这次应该执行里面,app\Http\Kernel 没有绑定过,而 missingLeadingSlash 我们前一章说过:

file

这里,逻辑不成立,不用多解释了吧,所以直接返回 app\Http\Kernel 字符串。

嗯哼,现在得到一个字符串了,不再是闭包对象了,应该有新的玩意可以学习,咱们继续往下:

isBuildable 判断成立,然后继续执行 build 方法。

前一章留下反射的伏笔,终于可以接触了,忘了反射的看第二章有详细例子。

Build 方法逻辑顺序:

先是我们最熟悉的闭包实例判断,我们这里只是一个字符串,所以不成立,再见。

然后 new 了一个反射类

file

呵呵,开始给 app\Http\Kernel 动手术了。

先是来了个 isInstantiable 判断,PHP 官网解释:

file

嗯哼,只要你不能实例化,直接抛错。

file

接下来又学到一个新数组

file

绑定栈,百度百科科普一下:

file

额,app\Http\Kernel 进入了栈结构了,废话!

紧接着又继续用到反射方法 getConstructor ,继续 PHP 官网:

file

在看下官方给的示例便于理解:

file

file

这下清楚了,如果反射不存在的话就返回一个 null

接下来也是一个 is_null 判断

file

注释很明了,不需要多余的工作,先是出栈,弹出 $concrete ,然后直接返回对象实例。

这里 app\Http\Kernel 继承了父类 Illuminate\Foundation\Http\Kernel ,并且有构造函数,这里先发一下构造函数原型,以便后面更容易理解:

file

那么现在我们还得继续往下分析,发一下 $constructor 调试截图,更清晰一点:

file

OK,那么现在 $constructor 是一个 ReflectionMethod 对象,这个反射方法对象我们在第二章也演示过,是针对类的方法。

紧接着

file

getParameters 方法示例:

file

file

一环扣一环,返回值依然是一个新对象,不过是针对参数。

调试截图:

file

嗯,确实匹配构造函数的参数,没什么大问题,每一个参数即是一个 ReflectionParameter 对象。

嗯哼,接下来也很关键:

file

keyParametersByArgument 的逻辑还没有实现,所以这里也略过,直接看 getDependencies 方法。

首先 $parameters 这里为空,$dependencies 为一个数组,每一个单元是一个 ReflectionParameter 对象。

这里也把依赖说的很直接了,变量名直接是 dependencies,也就是这些参数都是依赖。看看 getDependencies 是如何去解决这些依赖的。

file

其实只要咱们把新学的知识记熟的话,看起来 so easy。

首先声明一个数组变量,而 parameters 数组目前为止有2个单元,就是这2个参数

file

接着循环,前2层 if 都可以略过,没用到,第三层则调用了 resolveClass 方法。

对了,这个地方要特别提一下

file

这是 ReflectionParameter 对象的方法,用官网的语言还搞不明白,我就简答举个例子,第一个循环的$parameter 的参数是 app 对不,然后 $app 参数限定了必须继承于 Application 类,而 Application 类是 use 过的,如图:

file

getClass 方法最后的结果是这样:

file

返回了一个 ReflectionClass 对象,这样应该好理解些。

或者给你们一个传送门:

http://php.net/manual/zh/reflectionparamet...

OK,现在 dependency 变量是一个反射对象了,我们继续看下 resolveClass 又干了些什么?

file

好,我们先简化一下

$this->make(‘Illuminate\Contracts\Foundation\Application’)

Make 就不多说了,因为 application 类早在一开始就实例化好了,因为判断了 instances 数组,直接返回,至于下面的一个异常具体干什么,还没用到,就此略过。

我们回到build方法上来

file

OK,现在 $instances 是获得一个数组列表,分别有2个单元,分别对应了2个对象Illuminate\Foundation\ApplicationIlluminate\Routing\Router

接着出栈

file

最后很关键的地方来了

file

file

这个简单了吧,正好对应构造函数

file

嗯哼,原来是这样解决的依赖关系,真尼玛有套路啊。。

build 方法咱们算是理解了那么一些了。

返回到 make 方法

file

现在 $object 其实就是 app\Http\Kernel 类实例!

剩下的前一章都说了,没用到的依然没用到。

到了总结时刻

本章关键点在于 build 方法利用反射解决依赖关系那里,还有也进一步学习了 getClosure 方法内部逻辑,废话说多了不如自己多看多思考,我觉得反射部分大家可以深入思考一下,或许这个特性能使我们在 OOP 路上更上一层楼,我也还需要在消化消化,至此,启动完成,那么 kernel 接下来会带来哪些丰富的体验呢?

欢迎关注下一章!

本帖已被设为精华帖!
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 10
(= ̄ω ̄=)··· 暂无内容!

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