Thinkphp框架浅析(一)

thinkphp框架浅析(一) : url路由解析到类映射实例化加载原理剖析

  • 源码解读通过thinkphp test控制器test方法 探究thinkphp运行处理流程
  • 路径: thinkphp_5.0.7_core/application/index/controller/test.php
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <?php
    namespace app\index\controller;
    use think\Controller;
    class Test extends Controller
    {

    public function __construct()
    {
    parent::__construct();
    }

    public function index()
    {
    echo 'test/index';
    }

    public function test(){
    return 'hello word';
    }
    }
    基于最新版thinkphp_5.0.7_core
    • url访问http://localhost/thinkphp_5.0.7_core/public/index.php/test/test 入口文件 index.php
    1
    require __DIR__ . '/../thinkphp/start.php';
    • 加载基础文件
    1
    2
    require __DIR__ . '/base.php';
    // 这一步定义系统常量 环境变量 加载自动加载 、错误异常处理类 配置文件等
    • 加载完 集训执行 start.php 应用执行
    1
    App::run()->send();
    • App::run()
      进入run方法以后首先是一个try catch
      try中先是 初始化应用 self::initCommon(); 、绑定默认路由参数
    • 设置或获取当前的过滤规则 $request->filter($config['default_filter']);

    • 语言设置

    • url调度

    • url 路由检测 self::routeCheck($request, $config);

    • 通过 $request->path(); 获取请求路径信息 返回test/test

    • 路由检测 (根据路由定义返回不同的URL调度) Route::check($request, $path, $depr, $config['url_domain_deploy']);

    • 路由无效或未配置下执行 (解析模块/控制器/操作/参数… 支持控制器自动搜索)
      Route::parseUrl($path, $depr, $config['controller_auto_search']);
      此处默认返回格式

    1
    2
    3
    4
    5
    6
    7
    array (size=2)
    'type' => string 'module' (length=6)
    'module' =>
    array (size=3)
    0 => string 'index' (length=5)
    1 => string 'test' (length=4)
    2 => string 'test' (length=4)
    • 返回run方法接着执行
    • 记录当前调度信息 $request->dispatch($dispatch);
    • 记录路由和请求信息Log::record
    • 监听app_begin Hook::listen
    • 请求缓存检查
    • 根据$dispatch['type'] 获取内容 这里默认是module 执行
      $data = self::module($dispatch['module'], $config, isset($dispatch['convert']) ? $dispatch['convert'] : null);
    • model 方法中 Loader::controller 进入执行 组合class命名空间路径 这里$class = 'app\index\controller\Test'
    • App::invokeClass($class);
    • 反射实例化类
    1
    2
    3
    4
    5
    6
    7
    $reflect     = new \ReflectionClass($class);   //反射类
    $constructor = $reflect->getConstructor(); //初始构造方法
    if ($constructor) {
    $args = self::bindParams($constructor, $vars);
    } else {
    $args = [];
    }
    • 获取内容方法
      $reflect->newInstanceArgs($args); //这里就返回了 控制器输出的内容 hello wolrd
    • $data = self::module module绑定发调用控制器空 返回的就是方法index/test/test返回的内容了
    • response 处理
    • 监听app_end
      返回 response
      app send 方法将内容返回给用户 App::run()->send();