返回参考视频中的路......登陆

参考视频中的路由类,自己动手写一个,实现URL到类方法的映射

吴勇文2019-04-27 19:55:32295
<?php
/**
 * 路由解析类
 * 1.路由解析
 * 2.请求分发
 */

namespace pig;

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

    //PATHINFO
    protected $pathInfo = [];

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

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

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

        // 第一步:将查询字符串前后的/去掉,再按分隔符/拆分到数组中
        $queryStr = trim(strtolower($queryStr),'/');
        $queryArr = explode('/',$queryStr);
        $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数组的索引3开始,将剩余的元素全部做为参数进行处理
                $arr = array_slice($queryArr,'3');

                //键值对必须是成对出现,所以每次递增为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()->print()
        return $this;
    }

    //请求分发
    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);
    }

QQ图片20190427194550.png

路由类主要实现2个功能,路由解析和请求分发

路由解析首先要从url地址中获取$queryStr = $_SERVER['QUERY_STRING'],再将$queryStr解析成2个部分,模块、控制器、操作为一组,参数为另一组。请求分发就是将模块、控制器重新组合成新的路径,和操作、参数一起使用call_user_func_array([new $controller,$action],$this->params)系统自定义函数调用事先写好的操作中自定义的函数方法。


最新手记推荐

• 用composer安装thinkphp框架的步骤• 省市区接口说明• 用thinkphp,后台新增栏目• 管理员添加编辑删除• 管理员添加编辑删除

全部回复(0)我要回复

暂无评论~
  • 取消回复发送