简易路由解析类

Original 2019-03-02 19:15:27 251
abstract:<?php /**  * 路由解析类  * 1. 路由解析  * 2. 请求分发  */ namespace pig; class Route {     // 路由配置信息     pr
<?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/leaf/age/18
        // 1. 将查询字符串前后的 / 去掉, 在按分隔符 / 拆分到数组
        $queryStr = trim(strtolower($queryStr), '/');
        $queryArr = explode('/', $queryStr);
        // 过滤空字符
//        $queryArr = array_filter($queryArr);

        // 2. 解析出 $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_splice($queryArr, 3);
                // 键值对必须成对出现,所以每次递增2
                for ($i = 0; $i < count($arr); $i += 2) {
                    // 如果没有第二个参数, 则放弃
                    if (isset($arr[$i + 1])) {
                        $this->params[$arr[$i]] = $arr[$i + 1];
                    }
                }
        }
        // 返回当前对象实例,主要方便链式调用
        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);
    }

    // 获取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\\' . ucfirst($this->pathInfo['controller']);
    }


}

// 测试路由
$queryStr = $_SERVER['QUERY_STRING'];
echo $queryStr . '<hr>';

var_dump(explode('/', $queryStr));

$config = require __DIR__ . '/config.php';
$route = new Route($config['route']);
$route->parse($queryStr);
//var_dump($route->pathInfo);
//var_dump($route->params);

// 测试请求分发
// 先加载对应模块控制器类
require __DIR__ . '/../app/admin/controller/Index.php';
echo $route->dispatch();


Correcting teacher:西门大官人Correction time:2019-03-03 09:48:52
Teacher's summary:路由解析在MVC框架中占有非常重要的地位。其核心思想就是把用户输入的url解析成为php的类和方法

Release Notes

Popular Entries