Tp5.1路由实现

路由有关的类

RuleItem类,路由规则类,继承Rule类,一条路由规则就实例化一个RuleItem类,Rule::get()返回的就是RuleItem实例。

1、重要属性

$rule:路由规则字符串

$name:路由标识

$router:Router对象

$vars:传参的参数数组

$option:路由参数,多维数组,例如middleware。

check().这个就是根据访问的url等信息,匹配路由规则实例,如果匹配上,返回Module类对象,后面就是Module对象执行调度方法实现控制器和方法的执行。

RuleGroup类,分组路由,继承Rule类

$this->rules[],分类存放RuleItem对象。路由导入就是注册到到这个对象中。

check(),通过request对象得到请求方式get,post,遍历这个分组下面的所有RuleItem对象,执行RuleItem->check()。如果匹配上,会返回Module类对象,保存着匹配的信息。

Route类,路由类,操作路由规则对象的类,依赖RuleGroup类

 

get(),post()...依赖RuleGroup实例,导入路由对象

Module类,继承Dispatch,其实就是执行调度的类。

1、重要属性

$controller:访问的控制器名

$actionName:方法名

$request:Request对象,

$rule:RuleItem对象

2.重要的方法有

run()执行路由调度

TP5.1如何实现路由

1.路由规则导入,初始化应用initialize()的时候会启动路由初始化

扫描route目录下的所有文件,include进来,并且把数组import

// 导入路由配置
$rules = include $filename;
if (is_array($rules)) {
     $this->route->import($rules);
}

如果使用 Route::get('hello/:name', 'index/hello');则通过Route对象的get导入路由规则$this->group->addRule($rule, $route, $method, $option, $pattern);实质就是RuleGroup对象调用addRule方法

Route::get()返回的是RuleItem实例,所以后面的middle(),cache()等方法,都是调用RuleItem实例的方法。

1.创建路由规则实例RuleItem对象(一条路由就生成一条路由规则对象)

2.加入到RuleGroup类的属性$this->rules[$method] []= $ruleItem;以method为键

2.得到Module对象,并执行init方法

if (empty($dispatch)) {
    // 路由检测
     $dispatch = $this->routeCheck()->init();
 }
 public function __construct(Request $request, Rule $rule, $dispatch, $param = [], $code = null)
    {
        $this->request  = $request;
        $this->rule     = $rule;
        $this->app      = Container::get('app');
        $this->dispatch = $dispatch;
        $this->param    = $param;
        $this->code     = $code;

        if (isset($param['convert'])) {
            $this->convert = $param['convert'];
        }
    }

 

 

控制器的执行

在app的run方法中,下面这段就是执行控制器方法,从路由匹配中获取到Module对象,然后调用run方法,返回Response对象。

$this->middleware->add(function (Request $request, $next) use ($dispatch, $data) {
            return is_null($data) ? $dispatch->run() : $data;
        });

最终执行的是Module对象的exec()方法,获取到类名,通过容器实例化对象,然后通过反射执行对应的方法。

// 实例化控制器
            $instance = $this->app->controller($this->controller,
                $this->rule->getConfig('url_controller_layer'),
                $this->rule->getConfig('controller_suffix'),
                $this->rule->getConfig('empty_controller'));
//获取控制器方法的反射 
$reflect    = new ReflectionMethod($instance, $action);
//执行方法,返回方法的返回值
$data = $this->app->invokeReflectMethod($instance, $reflect, $vars);

//把返回值传入autoResponse生成Response对象
$response = Response::create($data, $type);
//根据type的类型,使用不同的类
public static function create($data = '', $type = '', $code = 200, array $header = [], $options = [])
    {
        $class = false !== strpos($type, '\\') ? $type : '\\think\\response\\' . ucfirst(strtolower($type));

        if (class_exists($class)) {
            return new $class($data, $code, $header, $options);
        }

        return new static($data, $code, $header, $options);
    }

  

数据的返回

Response方法调用send输出内容

会判断符合的数据格式为null,string,number, is_callable([ $content, '__toString', ]).其他数据格式会报variable type error。所以控制器的方法return 的数据需要以上的格式才行。

然后echo $data,把数据放入php的输出缓存中。进程结束后php会把缓存的数据返回给nginx。

echo

echo 不是一个函数,是一个PHP的语言结构,输出基本数据类型和对象(需要定义__toString魔术方法,不然会报错);

php输出缓存output_buffering

通过配置文件开启output_buffering = on, 默认打开,还可以设置大小。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

runtoweb3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值