详细解析Thinkphp5.1源码执行入口文件index.php运行过程

运行了public目录下的index.php文件后,tp的运行整个运行过程的解析

入口文件index.php代码如下:

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +---------------------------------------------------------------------- // [ 应用入口文件 ]
namespace think; // 加载基础文件
require __DIR__ . '/../thinkphp/base.php'; // 支持事先使用静态方法设置Request对象和Config对象 // 执行应用并响应
Container::get('app')->run()->send();

解析:

1. 执行require __DIR__ . '/../thinkphp/base.php'; 引入base.php,实现自动加载机制。自动加载机制的实现过程请看上一篇文章。

2. 重点解析这行代码:执行Container::get('app')->run()->send(); 通过容器注册App,并且执行think\App.php的run()方法,将执行到的结果给到think\Response.php的send()响应请求。

具体过程如下:

  1. 通过容器Container通过反射模式注册实例化app类
  2. 调用app类应用程序初始化run方法
    1. 初始化应用-run()
      1. 初始化应用-initialize()
        1. 设置环境变量目录,如runtime_path、vendor_path、app_path、root_path、route等。-initialize()
        2. 加载环境变量配置.env-initialize()
        3. 注册应用命名空间-initialize()
          1. 初始化应用-init()
        4. 找到当前运行模块
        5. 判断缓存配置文件是否存在,存在,则加载初始化文件init.php,不去读取应用或模块下的配置文件
        6. 不存在,则去读取应用或模块下的配置文件,如:tags、common、provider、middleware等
        7. 如果模块下拥有同样的配置,那么模块下的配置即覆盖应用下的配置
      2. 初始化数据库配置
      3. 读取语言包
      4. 路由初始化
    2. 路由检测
      1. 检测是否有缓存
      2. 是否开启强制路由
      3. 路由检测-$this->route->check($path, $must);【此时如果路由找不到,且路由中未定义miss,则在这里抛出异常。】
        1. 自动检测域名路由
          1. 检测域名路由
            1. 检测域名路由别名
            2. 检测URL绑定
            3. 路由组检测路由-RuleGroup->check()【一个请求地址遍历路由文件一个一个匹配,是否匹配中】
              1. 检测是否跨域路由设置,是则加跨域,跨域参数加在$this->option变量中
              2. 检测路由分组有效性,路由请求是否与路由设置一致,如请求类型、域名、参数等
              3. 检测路由前置行为,并通过容器方式注册钩子,并执行行为。所以,路由中的行为在路由检测中就执行了。
              4. 路由分组检测think\Route\RouteItem->check();
              5. 匹配中路由,返回路由分发地址
            4. 匹配中路由,通过中间件过度执行路由匹配结果,$response = $this->middleware->dispatch($this->request);【如果路由找不到,且路路由中定义了miss,则在这里跑出miss对应的路由。】
              1. 如果有绑定中间件,则执行中间件。如果中间件接手返回机制,返回一个response对象,则不会执行路由的分发机制。否则,中间件执行完,执行到return $next($request);的时候,继续执行路由的分发机制-think\Route\Dispatch。
              2. 执行路由分发机制-think\Route\Dispatch的时候才执行路由的后置行为。【路由后置行为建议使用中间件替代】(来自源码)
    3. 执行完run。返回执行结果。【路由分发的执行结果(来自控制器)或中间件的执行结果】
    4. 执行think\Response的send()响应请求。【注意:如果代码中自定义了返回机制,且die或exit,则不会走到这一步,则路由中定义的header跨域之类的也因此不会生效,需要自定义header返回处理】
 
 
 

详细解析Thinkphp5.1源码执行入口文件index.php运行过程的更多相关文章

  1. Yii2 源码分析 入口文件执行流程

    Yii2 源码分析  入口文件执行流程 1. 入口文件:web/index.php,第12行.(new yii\web\Application($config)->run()) 入口文件主要做4 ...

  2. .1-浅析express源码之入口文件

    鸽了鸽了,webpack源码大垃圾,看了那么久,感觉自己越来越渣……还是换个口味,node了解一下? 尝试从express框架源码入手,学习一下node的http模块相关的知识. 入口文件 先从框架的 ...

  3. Spark源码系列(三)作业运行过程

    作业执行 上一章讲了RDD的转换,但是没讲作业的运行,它和Driver Program的关系是啥,和RDD的关系是啥? 官方给的例子里面,一执行collect方法就能出结果,那我们就从collect开 ...

  4. MyBatis 源码分析 - 映射文件解析过程

    1.简介 在上一篇文章中,我详细分析了 MyBatis 配置文件的解析过程.由于上一篇文章的篇幅比较大,加之映射文件解析过程也比较复杂的原因.所以我将映射文件解析过程的分析内容从上一篇文章中抽取出来, ...

  5. Python 多线程、多进程 (一)之 源码执行流程、GIL

    Python 多线程.多进程 (一)之 源码执行流程.GIL Python 多线程.多进程 (二)之 多线程.同步.通信 Python 多线程.多进程 (三)之 线程进程对比.多线程 一.python ...

  6. 全网最详细的AbstractQueuedSynchronizer(AQS)源码剖析(二)资源的获取和释放

    上期的<全网最详细的AbstractQueuedSynchronizer(AQS)源码剖析(一)AQS基础>中介绍了什么是AQS,以及AQS的基本结构.有了这些概念做铺垫之后,我们就可以正 ...

  7. rest_framework解析器组件源码流程

    rest_framework解析器组件源码流程 解析器顾名思义就是对请求体进行解析.为什么要有解析器?原因很简单,当后台和前端进行交互的时候数据类型不一定都是表单数据或者json,当然也有其他类型的数 ...

  8. 曹工说Redis源码(3)-- redis server 启动过程完整解析(中)

    文章导航 Redis源码系列的初衷,是帮助我们更好地理解Redis,更懂Redis,而怎么才能懂,光看是不够的,建议跟着下面的这一篇,把环境搭建起来,后续可以自己阅读源码,或者跟着我这边一起阅读.由于 ...

  9. 曹工说Redis源码(5)-- redis server 启动过程解析,以及EventLoop每次处理事件前的前置工作解析(下)

    曹工说Redis源码(5)-- redis server 启动过程解析,eventLoop处理事件前的准备工作(下) 文章导航 Redis源码系列的初衷,是帮助我们更好地理解Redis,更懂Redis ...

随机推荐

  1. openmp学习心得(一)

    主要在vs2015下使用OMP,写一些自己omp的学习心得: 一.在VS2015下OpenMP的使用: 1.VS2015也仅仅支持OpenMP2.0版本,VS对OpenMP的支持并不太好. 2.在VS ...

  2. Sharding-JDBC基本使用,整合Springboot实现分库分表,读写分离

    结合上一篇docker部署的mysql主从, 本篇主要讲解SpringBoot项目结合Sharding-JDBC如何实现分库分表.读写分离. 一.Sharding-JDBC介绍 1.这里引用官网上的介 ...

  3. Ubuntu 16.04 curl 安装 使用

    curl是利用URL语法在命令行方式显工作的开元文件传输工具. 安装 $ sudo apt install -y curl 使用 $ curl http://www.baidu.com 这是最简单的使 ...

  4. Windows内核基础知识-5-调用门(32-Bit Call Gate)

    Windows内核基础知识-5-调用门(32-Bit Call Gate) 调用门有一个关键的作用,就是用来提权.调用门其实就是一个段. 调用门: 这是段描述符的结构体,里面的s字段用来标记是代码段还 ...

  5. Access的分页代码

    if giPage = 1 then begin sSQL := 'SELECT TOP 10 * FROM dw_demo WHERE '+sWhere +' ORDER BY '+sOrder+' ...

  6. 用tsc编译ts文件的时候报错,tsc : 无法加载文件,因为在此系统上禁止运行脚本;

    用tsc编译ts文件的时候报错,tsc : 无法加载文件,因为在此系统上禁止运行脚本:SecurityError 在vscode的控制台或者Windows PowerShell中用tsc命令编译ts文 ...

  7. Java 17 新功能介绍(LTS)

    点赞再看,动力无限.Hello world : ) 微信搜「程序猿阿朗 」. 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章. Jav ...

  8. 前端调试工具DevTools处理网络请求

    DevTools处理网络请求 位置:network 1.是否启用网络处理功能 2.清除历史 3.过滤器,自定义筛选 4.是否保留先前的历史,因为每次刷新会删除历史重新加载,选中后新老请求都在可做对比 ...

  9. BAT面试必问细节:关于Netty中的ByteBuf详解

    在Netty中,还有另外一个比较常见的对象ByteBuf,它其实等同于Java Nio中的ByteBuffer,但是ByteBuf对Nio中的ByteBuffer的功能做了很作增强,下面我们来简单了解 ...

  10. spring笔记-MultiValueMap

    即一个键对应多个值,Spring的内部实现是LinkedMultiValueMap MultiValueMap接口 一键多值的使用场景是比较多的,在使用该数据结构之前,通常会自己定义 Map<K ...