ThinkPHP6 焦点剖析之Http 类跟Request类的实例化

admin 2个月前 (07-24) 科技 33 0
以下源码剖析,我们可以从 APP,Http 类的实例化历程,领会类是若何实现自动实例化的,依赖注入是怎么实现的。

从入口文件出发

当接见一个 ThinkPHP 搭建的站点,框架最先是从入口文件最先的,然后才是应用初始化、路由剖析、控制器挪用和响应输出等作。 &NBsp; 入口文件主要代码如下:  

App 实例化

执行 new App() 实例化时,首先会挪用它的组织函数。     组织函数实现了项目种种基础路径的初始化,并读取了 provider.php 文件,将其类的绑定并入 $bind 成员变量,provider.php 文件默认内容如下:     并后,$bind 成员变量的值如下:     $bind 的值是一组类的标识到类的映射。从这个实现也可以看出,我们不仅可以在 provider.php 文件中添加标识到类的映射,而且可以笼罩其原有的映射,也就是将某些焦点类替换成自己界说的类。   static::setInstance($thIS) 实现的作用,如图:     think\App 类的 $instance 成员变量指向 think\App 类的一个实例,也就是类自己保留自己的一个实例。 instance() 方式的实现:     其中的getAlias方式:     执行效果大概是这样的:  

Http 类的实例化以及依赖注入原理

这里,$http = (new App())->http,前半部门好明白,后半部门乍一看有点让人摸不着头脑,App 类并不存在 http 成员变量,这里何以勇敢挪用了一个不存在的东东呢?   原来,App 类继续自 Container 类,而 Container 类实现了__get() 魔术方式,在 PHP 中,当接见到的变量不存在,就会触发__get() 魔术方式。该方式的实现如下:     实际上是挪用get()方式:     然而,实际上,主要是make()方式:     然而,make()方式主要靠invokeClass()来实现类的实例化。该方式详细剖析:     以上代码可看出,在一个类中,添加__make()方式,在类实例化时,会最先被挪用。以上最值得一提的是bindParams()方式:     而这之中,又最值得一提的是getObjectParam()方式:     getObjectParam() 方式再一次名誉地挪用 make() 方式,实例化一个类,而这个类,正是从 Http 的组织函数提取的参数,而这个参数又恰恰是一个类的实例 ——App 类的实例。到这里,程序不仅通过 PHP 的反射类实例化了 Http 类,而且实例化了 Http 类的依赖 App 类。若是 App 类又依赖 C 类,C 类又依赖 D类…… 不管若干层,整个依赖链条依赖的类都可以实现实例化。   总的来说,整个历程大概是这样的:需要实例化 Http 类 ==> 提取组织函数发现其依赖 App 类 ==> 最先实例化 App 类(若是发现另有依赖,则一直提取下去,直到天荒地老)==> 将实例化好的依赖(App 类的实例)传入 Http 类来实例化 Http 类。   这个历程,起个装逼的名字就叫做「依赖注入」,起个摸不着头脑的名字,就叫做「控制反转」。   这个历程,若是退回远古时代,要实例化 Http 类,大概是这样实现的(若是有很层依赖):     这得有多累人。而现代 PHP,交给「容器」就好了。   另外,需要提的一点是 make 方式的 $vars 参数,它的形式可以是通俗数组、关联数组,而且数组中元素的值可以是一个类的实例。$vars 参数的值最终将传递给要实例化的类的组织函数或者__make 方式中对应的参数。  

Request 类的实例化

接上一面,获得Http类的一个实例后,程序接下来执行$response = $http->run();。其中run()方式代码如下:    

从「request」标识找到要实例化的类

run() 方式的第一行通过容器类实例 app 挪用 make() 方式并传入 Request 类的标识来实例化 Request 类。详细历程如下剖析。   通过 make() 方式首先剖析获得 request 标识对应的标识 think\Request, 进一步递归剖析,又获得 app\Request 类 —— 这个才是最终要实例化的类。   app\Request 类对应的文件位于 app 目录下,代码如下:     实际上它啥事也没干,直接继续系统的 \think\Request。固然我们也可以在这里对系统的 Request 类举行改写重构。

挪用 invokeClass () 方式

从类的标识剖析获得最终需要实例化的类(单例模式下,且该类还不存在实例)之后,程序挪用 invokeClass () 方式,通过 PHP 的反射类实现类的实例化。由于 \think\Request 类存在__make() 方式,以是实例化之前首先挪用该方式。__make() 方式代码如下:     __make()方式首先实例化think\Request类自身。think\Request类组织函数如下:     组织函数读取了 php://input 保留起来。接着,__make() 方式保留了一些请求相关的数据,最后返回一个 Request 类实例。最后的最后, make() 方式也乐成获得该实例,整个历程跟 Http 类的实例化类似。该 Request 类实例部门成员变量如图:  

保留「Request」类的实例到「$instances」数组

获得 Request 类的实例后,run() 方式接着将该实例保留到「$instance」数组,以便后面单例模式要用到时可以直接获取。$instances 数组的值如图,Request 类的实例已保留在里面:      ,

联博API

www.326681.com采用以坊区块链高度哈希值作为统计数据,联博以太坊统计数据开源、公平、无任何作弊可能性。联博统计免费提供API接口,支持多语言接入。

Sunbet声明:该文看法仅代表作者自己,与本平台无关。转载请注明:ThinkPHP6 焦点剖析之Http 类跟Request类的实例化

网友评论

  • (*)

最新评论

站点信息

  • 文章总数:621
  • 页面总数:0
  • 分类总数:8
  • 标签总数:1120
  • 评论总数:255
  • 浏览总数:6874