返回手写URL到类......登陆

手写URL到类的方法映射

JasonKim2019-04-14 12:23:39256
<?php

// 路由解析类
namespace Pigs;

class Routes
{
    // 默认路由
    protected $route = [];

    // pathInfo 信息
    protected $pathInfo = [];

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

    // 创建构造方法
    public function __construct($route)
    {
        $this->route = $route;
    }

    // 解析路由
    public function parse($queryStr='')
    {
        // 处理字符串信息,去掉左右两边的/ 并把字母全部转换成小写
        $queryStr = trim(strtolower($queryStr),'/');
        // 将字符串分割成数组
        $queryArr = explode('/',$queryStr);

        // 判断解析的数组个数,获取(模块,控制器,操作,参数)
        switch(count($queryArr))
        {
            // 如果为0 则使用默认路由
            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
                $count = count($arr);
                for($i=0;$i<$count;$i+=2)
                {
                    // 如果没有第二个参数,则放弃
                    if(isset($arr[$i+1]))
                    {
                        $this->params[$arr[$i]] = $arr[$i+1];
                    }
                }
                break;
        }

        // 返回当前路由的实例对象,主要是方便链式调用:$route->parse
        return $this;
    }

    // 请求分发
    public function dispatch()
    {
        // 获取模块
        $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:/');
        }

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

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

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

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


// 获取地址信息
$queryStr = $_SERVER['QUERY_STRING'];
// 导入路由信息
$config = require 'config.php';
// 传入默认路由
$route = new Routes($config['route']);
echo '<pre>';
$rs = $route->parse($queryStr);

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

?>


最新手记推荐

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

全部回复(0)我要回复

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