路由解析类小练习

Original 2019-04-06 19:12:11 214
abstract:<?php /**  * 路由解析类  * 1.路由解析  * 2.请求分发  */ namespace pig; class Route {     //路由配置参数     protected $rout
<?php
/**
 * 路由解析类
 * 1.路由解析
 * 2.请求分发
 */

namespace pig;


class Route
{
    //路由配置参数
    protected $route = [];

    //PATHINFO解析模块
    protected $pathInfo = [];
//为了测试把私有属性protected修改成public
//    public $pathInfo = [];

    //URL参数数组
    protected $params = [];
//    public $params = [];

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

    //解析路由
    public function parse($queryStr='')
    {
        //  /admin/user/add/name/zhu/age/30
        //  解析模块:$this->pathInfo =['module'=>'admin','controller'=>'user','action'==>'add']
        //  参数数组:$this->params = ['name'=>'zhu','age'=>30]

        //第一步:将字符串前后的/去掉,再按分隔符/拆分到数组中
        // http://pig.io/pig/route.php?admin/user/add/name/zhu/age/30  结果: /admin/user/add/name/zhu/age/30
        //1.strtolower($queryStr)转换成小写,trim去掉前后/
        //$queryStr = trim(strtolower($queryStr),'/');
        $queryStr = trim(strtolower($queryStr),'/');
        //2.用explode('/',$queryStr)切割
        $queryArr= explode('/',$queryStr);
        //3.用array_filter()过滤空值,0会当成false
        //$queryArr = array_filter($queryArr);

        //第二步:解析出$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数组的索引开始,将剩余的元素全部作为参数来处理
                $arr = array_slice($queryArr,3);
                //从第4个元素进行处理,键值对必须成对出现,每次递增2,每2个一组进行处理
            for($i=0;$i < count($arr);$i += 2){
                //如果没有第二个参数,则放弃
                if(isset($arr[$i+1])){
                    //参数键值对处理
                    $this->params[$arr[$i]] = $arr[$i+1];
                }
            }
                break;
        }
        //返回当前路由的实例对象,主要是方便链式调用:$route->parse()->worm()
        return $this;
    }
    //请求分发
    public function dispatch()
    {
        //生成的带有命名空间的控制器类名称:app\模块\controller\控制器类
        //类名称与类文件所在的绝对路劲一一对应,实现自动映射,方便加载
        //模块名称
        $module = $this->pathInfo['module'];

        //控制器名称  获取绝对路径:'app\\' . $module .'\controller\\' .
        $controller = 'app\\' . $module .'\controller\\' . ucfirst($this->pathInfo['controller']);
       //die($controller);


        //操作名
        $action = $this->pathInfo['action'];
        //判断$controller是否存在$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->route['module'];
    }

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

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


$config = require 'config.php';
//实例化Route(),放在变量中
$route = new Route($config['route']);
$route->parse($queryStr);
//显示模块/控制器/方法
print_r($route->pathInfo);
//显示参数
print_r($route->params);
//对象的形式调用
//print_r($route->parse());

//测试请求分发
require __DIR__ .'/../app/admin/controller/Index.php';
echo $route->dispatch();


Correcting teacher:天蓬老师Correction time:2019-04-08 10:12:46
Teacher's summary:你这是把教学代码全部复制上来, 真的懂了吗

Release Notes

Popular Entries