PHP程序员小白到大牛集训(12期免息)

我的路由解析类

原创2019-01-02 14:25:30130
摘要:路由解析类  1、路由解析  2、请求分发 <?php namespace pig; echo '<pre>'; class Route {     //路由的配置信息     protected $route 
路由解析类
 1、路由解析
 2、请求分发
<?php

namespace pig;
echo '<pre>';

class Route
{
    //路由的配置信息
    protected $route = [];

    //PATHINFO
    protected $pathInfo = [];

    //url参数
    protected $param = [];

    //构造方法
    public function __construct($route)
    {
        //路由配置初始化
        $this->route = $route;
    }

    #解析路由
    public function parse($queryStr='')
    {
        $queryStr = $_SERVER['QUERY_STRING'];

        #第一步:将查询字符串前后的/去掉,再按分隔符/拆分到数组中
        $queryStr = trim(strtolower($queryStr),'/');
        $queryArr = explode('/',$queryStr);

        #第二步:解析出 $queryArr 数组中的内容(模块、控制器、操作、参数)
        switch (count($queryArr)){
            //没有参数,则使用默认的模块/控制器/操作
            case 0:
                $this->pathInfo = $this->route;
                break;
            //只有一个参数,用户只提供了模板,控制器和操作使用默认值
            case 1:
                $this->pathInfo['module'] = $queryArr[0];
                break;
            //两个参数:模块和控制器自定义,操作是默认的
            case 2:
                $this->pathInfo['module'] = $queryArr[0];
                $this->pathInfo['controller'] = $queryArr[1];
                break;
            //三个参数:模块/控制器/操作 全部自定义:全部来自用户的实际请求
            case 3:
                $this->pathInfo['module'] = $queryArr[0];
                $this->pathInfo['controller'] = $queryArr[1];
                $this->pathInfo['action'] = $queryArr[2];
                break;
            //对参数进行处理
            default:
                $this->pathInfo['module'] = $queryArr[0];
                $this->pathInfo['controller'] = $queryArr[1];
                $this->pathInfo['action'] = $queryArr[2];

            //从pathInfo数组的索引3开始,将剩余的元素全部作为参数进行处理
            $arr = array_slice($queryArr,3);
            for ($i=0;$i<count($arr);$i+=2){
                //如果没有第二个参数,则放弃
                if (isset($arr[$i+1])){
                    $this->params[$arr[$i]] = $arr[$i+1];
                }
            }
            break;
        }
        //返回当前路由的实际对象
        return $this;
    }

    //请求分发  将module、controller、action形成请求地址,找到对应的脚本
    public function dispatch(){
        //生成的带有命名空间的控制器类名称:app\模块\controller\控制器类
        //类名称应该与类文件所在的绝对路径一一对应,这样才可以实现自动映射,方便自动加载
        //模块名称
        $module = $this->pathInfo['module'];

        //控制器名称
        $controller = 'app\\'.$module.'\controller\\'.ucfirst($this->pathInfo['controller']);

        //操作名
        $action = $this->pathInfo['action'];

        if (!method_exists($controller,$action)){
            $action = $this->route['action'];
            header('Location:/');
        }

        #将用户的请求分发到指定的控制器和对应的操作方法上
        return call_user_func_array([new $controller,$action],$this->params);
    }

//    其他操作
    //获取pathInfo
    public function getPathInfo(){
        return $this->pathInfo;
    }

    //获取模板
    public function getModule(){
        return $this->pathInfo['module'] ? : $this->pathInfo['module'];
    }

    //获取控制器
    public function getController(){
        return 'app\\'.$this->getModule().'\controller\\'.$this.$this->pathInfo['controller'];
    }


}

//测试路由
$queryStr = $_SERVER['QUERY_STRING'];
print_r(explode('/',$queryStr));
echo '<hr>';

$config = require 'config.php';
$route = new Route($config['route']);   #初始化使用 config 中的 route 数组
$route->parse($queryStr);
//print_r($route->route);
//print_r($route->pathInfo);
//print_r($route->params);

//测试请求分发
require __DIR__.'/../app/admin/controller/Index.php';
echo $route->dispatch();
//访问 http://frame.io/pig/Route.php?admin/index/index  admin模块 index控制器 index方法

结果:

作业.png

批改老师:天蓬老师批改时间:2019-01-02 14:30:17
老师总结:你这是照着抄了一遍呀, 理解了吗?

发布手记

热门词条