探究Thinkphp URL路由流程

  • 探究thinkphp URL路由流程
    主流程 : > URL访问 > 路由配置参数解析 > 路由匹配实例化

探究thinkphp如何实现路由访问?怎么实现?

  • index模块建立test控制器id()方法

路径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
<?php
namespace app\index\controller;

use think\console\command\make\Model;
use think\Controller;
use think\Route;

class Test extends Controller
{
public function id()
{
$id = input('id');
return sprintf('current page id %s',$id);
}
}
  • 配置路由

thinkphp_5.0.7_core/application/route.php 加入

1
2
3
'[test]'     => [
':id' => ['test/id', ['method' => 'get'], ['id' => '\d+']],
],
  • 访问

URL:http://localhost/thinkphp_5.0.7_core/public/index.php/test/1

  • 探究thinkphp框架源码如何将test/1转到 test/id
  • 代码解读
  • 入口文件进入
  • index.php -> require __DIR__ . '/../thinkphp/start.php';
    • run()方法
  • 源码App::run()->send();
  • 先执行App::run()
    • 进入App.php run方法
  • 初始化配置
  • 读取多语言
  • 应用调度 $dispatch = self::$dispatch; 这里默认返回NULL 所以会走URLlu有检测
    $dispatch = self::routeCheck($request, $config);
  • 路由检测
  • 读取路由配置是否开启
  • 读取路由配置参数 Route::import($rules);
  • 路由检测(根据路由定义返回不同的URL调度)Route::check

路由检测 check

  • 根据请求类型获取对应路由规则
  • 检测部署域名
  • URL绑定
  • 如果解析到路由 就执行 路由规则检测 self::checkRoute

路由规则检测

  • 通过路由检测方法 最终发出路由解析完参数配置数组
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // +----------------------------------------------------------------------
    // array (size=3)
    // 'type' => string 'module' (length=6)
    // 'module' =>
    // array (size=3)
    // 0 => null
    // 1 => string 'test' (length=4)
    // 2 => string 'id' (length=2)
    // 'convert' => boolean false
    // +----------------------------------------------------------------------
  • 第一次进入
1
$rules = array('test' => true);
  • 执行 $item = self::getRouteExpress($key);
  • 执行 if (is_array($rule))
  • 自调一次
  • 第二次进入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$rules =  array (size=1)
0 =>
array (size=5)
'rule' => string ':id' (length=3)
'route' => string 'test/id' (length=7)
'var' =>
array (size=1)
'id' => int 1
'option' =>
array (size=1)
'method' => string 'get' (length=3)
'pattern' =>
array (size=1)
'id' => string '\d+' (length=3)
  • 路由规则检查 self::checkRule 返回路由 模块 控制器 方法

    路由匹配 self::match

  • 解析路由规则 self::parseRule
  • 解析URL地址 模块/控制器/方法 self::parseModule($route)
  • 找到返回源了
    1
    return ['type' => 'module', 'module' => [$module, $controller, $action], 'convert' => false];

  • 中间省略

后续步骤

  • 后续组合路由配置参数 > 解析成命名空间格式 > 映射实例化 > 获取映射方法内容返回

    最终执行 send()将内容发送给客户端

总结

  • 流程简要回顾
  • 进入run 方法执行 -> 相关项目加载
    -> 路由检测 self::routeCheck -> 读取路由配置文件 -> 路由检测 Route::check -> 路由规则检测 self::checkRoute -> 进入第一次 $rules 不包含路由规则 -> 执行self::getRouteExpress($key) 加载路由规则 -> 自调一次 -> 第二次进入 包含规则信息 -> 执行self::checkRule -> 对路由规则参数组合 -> 返回模块、控制器、方法信息
    -> 执行映射类 -> 返回方法内容 -> 返回用户请求

    • 简单来说

    就是将请求地址中的参数解析 -> 与路由中配置 -> 进行匹配 -> 如果存在就返回配置中对应模块、控制器、方法,后续实例化方法返回给客户端。