详细解析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. C/C++ 数据类型 表示最大 最小数值 探讨

    C/C++中存储数字格式有整型和浮点型 字符型数据本质上也是以整型存储 整型 对于整型数据,最大值最小值很好计算 先确定对应数据型在本地所占用的字节数,同一数据型由于系统或者编译器的不同,所占字节不同 ...

  2. OO_JAVA_电梯运行模拟_单元总结

    电梯运行模拟--三次作业总结 目录 电梯运行模拟--三次作业总结 总体遵循的设计思路 逻辑解耦 电梯与调度器解耦 楼层信息的存储和变更与电梯.调度器解耦 调度器运行流程解耦 第一次电梯,蠢笨串行先到先 ...

  3. Machine learning (7-Regularization)

    1.The Problem of Over-fitting 2.Cost Function 3.Regularized Linear Regression 4.Regularized Logistic ...

  4. Redis的浅入门

    Redis的浅入门 # 缓存的思想 问题提出:我们的用户数量上亿,如果登录,访问数据库user特别耗时,该怎么办?--提出缓存 方法:怎样从缓存在获取数据? *有数据: 直接返回 *无数据: (1)从 ...

  5. 算法:Z字型(Zigzag)编排

    问题:给定 n 行和 m 列的二维数组矩阵.如图所示,以 ZIG-ZAG 方式打印此矩阵. 从对称的角度来看,通过反复施加滑行反射可以从简单的图案如线段产生规则的之字形. 主要思想:算法从(0, 0) ...

  6. 栈的压入、弹出顺序 牛客网 剑指Offer

    栈的压入.弹出顺序 牛客网 剑指Offer 题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是 ...

  7. insertion-sort-list leetcode C++

    Sort a linked list using insertion sort. C++ /** * Definition for singly-linked list. * struct ListN ...

  8. SpringCloud微服务实战——搭建企业级开发框架(十五):集成Sentinel高可用流量管理框架【熔断降级】

      Sentinel除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一.由于调用关系的复杂性,如果调用链路中的某个资源不稳定,最终会导致请求发生堆积.Sentinel ...

  9. 限制q-error,防止产生次优计划

    原文:<Preventing bad plans by bounding the impact of cardinality estimation errors> 摘要 文章定义了一个衡量 ...

  10. oracle基础:怎样把查询的null转换为0、打印、定义变量

    https://blog.csdn.net/xuxile/article/details/49943665 oracle怎样把查询的null转换为0 1.查询的null转换为0 NVL(Expr1,E ...