thinkphp 核心源码分析

thinkphp 版本 6.0.*

分析PHP框架源码比较方便从入口开始就行

找到public/index.php就可以开整了

namespace think;

if (version_compare("7.3", PHP_VERSION, ">=")) {
    die("PHP 7.3 or greater is required");
}

require __DIR__ . '/../../vendor/autoload.php';

// 执行HTTP应用并响应
$http = (new App())->http;

$response = $http->name('admin')->run();

$response->send();

$http->end($response);

index.php 比较简单总共不超过10行

前几行没啥分析的 判断PHP版本 加载 Composer 自动加载

重点在 App() 类实例化后面这几行

App类定义在 vendor\topthink\framework\src\think\App.php 里面

首先可以看到App继承了容器类 ,说明App类是可以作为容器来使用的

再来看它的构造方法

首先定义了一堆路径

比较重要的是项目入口目录其他的目录都是在基于这个目录上拼接的

然后是 bind 方法调用  这个方法涉及到容器的操作了。容器是依赖注入设计模式的核心不了解的自行百度即可

具体到 App 类容器相关的操作 主要说明下 bind,make,invoke这几个 方法这些方法都是继承自Container

bind  使用别名和实际类 建立相关映射关系 

make  获取容器内的类实例,容器内不存在类实例时自动创建并且放入容器。

invoke 这个方法主要用来主动调用其他方法时对方法参数自动注入

 new App 做的比较简单 下面继续退回到 public/index.php分析下一段

new App()->http 

获取http 属相? 查询源码 App类 和其父类 并没有 http 这个属性它从哪来的?

继续寻找 ,找到 App父类 Container类上有个 __get 魔术方法 那么应该是调用了这个方法了

跟踪__get方法实际是调用了make 方法获取了容器内的对象http 。

那http 是从哪里建立映射关系的呢?

Container 绑定建立映射是存放在属性 bind 中的App类覆盖了该属性并且 初始就默认了一堆核心类的映射关系(bind这个属性名称写的...)

从这里找到http属性就是vendor\topthink\framework\src\think\Http类的实例

接着继续public/index.php 往下看

$response = $http->name('admin')->run();

这行调用 Http类型实例 name方法设置应用名称后面会使用到

接下来是重要的run方法 此方法包含 中间件、路由匹配、分配模块控制器 等核心操作

详细分析下

第一行进行初始化 分析后最终 是进行了 调用$this->app->initialize();

App 类的初始化方法 initialize 是框架最核心的初始化

初始化具体操作包括 :设置已初始化标志、运行开始时间、内存信息保存、加载配置文件、设置运行模式、加载服务 初始化服务....

初始化后继续回退到Http类实例的run 方法中

接着是调用了自身的 runWithRequest 方法 

此方法第一行加载中间件,加载逻辑就不详细描述了

第二行触发HttpRun事件  (对于Web应用开发 事件这块感觉用处不大,主要用于核心插件开发时使用 例如 think-multi-app 组件)

最后一行是核心逻辑使用了联级调用,因为很重要 所以一段一段的开始分析

$this->app->middleware 这一段主要是获取容器中的middleware 中间件管理类型实例具体获取方式参照http实例的获取. 

->pipeline()  这一段 注释标注为 调度管道 

pipeline 这个函数里面的代码写的有些杂乱,不好分析

先忽略那些复杂的参数逻辑先看主流程  首先new 了Pipeline 类的实例 然后联级调用了 实例的 through 、whenException方法

这里理解 Pipeline 这个类的作用就比较重要了

先说下Pipeline 类名字 翻译过来就是管道线,实际这个类主要功能是栈的工具类 

Pipeline:: through 方法起到入栈的功能入栈的东西是什么呢 是匿名函数 也就是 Closure 类的实例

Pipeline ::send 方法绑定入参 也就是传入栈类匿名函数的入参

Pipeline ::then 方法 按照 栈的逻辑 先进后出的方式执行 栈内的匿名函数

下面简单说下   Pipeline 类的具体实现流程

首先Pipeline:: through 方法将 参数 匿名函数数组  保存到内部属性 pipes 作为栈空间,Pipeline ::then方法巧妙的借助 array_reduce() 函数对 匿名函数 进行出栈 的顺序递归的方式调用

分析完 Pipeline 后 $this->app->middleware->pipeline() 的调用就比较好分析了 

pipeline() 方法将 中间件 的调用封装在 匿名函数中

接着继续分析 $this->app->middleware->pipeline()->send($request)  send 将  request对象实例绑定到Pipeline类实例,为下面的匿名函数执行时做为参数

继续往下  分析then 方法

  $this->app->middleware->pipeline()
            ->send($request)
            ->then(function ($request) {
                return $this->dispatchToRoute($request);
            });   

then 方法通过把数组 Pipeline.pipes前面一个 匿名函数 作为后面一个匿名函数的参数$next 。来实现依次出栈 递归调用

$this->dispatchToRoute($request); 被  array_reduce() 作为初始函数 内的代码 它的执行权被交给了最后一个 全局中间件的 方法

具体中间件中的逻辑 暂时不进行分析,继续分析主流程 $this->dispatchToRoute($request); 这行的逻辑

dispatchToRoute 通过方法名称来分析 对路由进行调度

通过查看源码 dispatchToRoute 发现程序将控制器交给了  route::dispatch 方法

通过App类的初始映射得知 route 对应的是 vendor\topthink\framework\src\think\Route类实例

前面两行是对参数进行保存没啥可分析的

接着判断了是否启用自定义路由,如果启用了自定义路由则通过配置的自定义规则来解析未启用自定路由规则 则按照默认规则解析 

$dispatch 变量是 vendor\topthink\framework\src\think\route\dispatch\Url 类的实例

Url 类 继承至 vendor\topthink\framework\src\think\route\dispatch\Controller

Controller 类继承至 vendor\topthink\framework\src\think\route\Dispatch

这里感觉有点奇怪...

 $dispatch->init($this->app); 这一行包括了具体路径解析到控制器、 

下面 连级调用 与之前 全局中间件类似 不做详细解析

$dispatch->run();  run 方法调用了 Controller ::exec  

Controller ::exec  反射调用具体controller 和method

到这里thinkphp的主流程基本结束了

回到public/index.php

$response->send();  方法主要 输出数据

$http->end($response); 处理输出结束后的中间件end 操作

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ThinkPHP是一款开源免费的PHP开发框架,而ThinkPHP 3.0是ThinkPHP框架的一个版本。ThinkPHP 3.0源码是指这个版本框架的源代码,通过阅读和理解源码,我们可以深入了解框架的设计思想、工作原理以及具体的实现方式。 ThinkPHP框架的源码以MVC(Model-View-Controller)模式组织,将应用程序分为模型、视图和控制器三个层次。其中,模型层用于处理数据、数据库操作等;视图层负责用户界面的展示;控制器层负责接受用户请求,进行逻辑处理,并将结果返回给用户。 ThinkPHP 3.0源码核心部分包括路由解析、请求分发、调度机制、缓存管理、数据库操作等。框架通过路由解析来将用户的请求转发给对应的控制器进行处理,同时支持URL重写、多模块或子域名部署等高级路由功能。框架还提供了灵活的请求分发机制,可以对请求进行过滤、日志记录、权限控制等操作。 另外,ThinkPHP 3.0源码还提供了丰富的扩展和插件机制。开发者可以通过自定义的扩展或插件来增加框架的功能或修改特定的行为,从而更好地满足自己的需求。这种可扩展性使得ThinkPHP成为一个非常灵活的框架,适用于各种规模和类型的项目。 总之,通过深入研究ThinkPHP 3.0源码,我们可以更好地理解框架的工作原理和设计思想,从而能够更高效地使用和开发基于ThinkPHP的应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值