$_SERVER['QUERY_STRING']和call_user_func_array()

原创 2018-12-18 11:12:36 222
摘要:class Route {     //路由配置信息     protected $route = [];     //PATHINFO     protected $pathInfo&nb
class Route
{
    //路由配置信息
    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);
            $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;
            }
         //返回当前类的实例,这样就可以实现链式调用,即直接用->调用另一方法,省去重复写对象
        return $this;
    }
    //请求分发
    public function dispatch()
    {
        //生成控制器类名称: app\模块\controller\控制器类;
        //模块名
        $module = $this->pathInfo['module'];
        //控制器名
        $controller = '\app\\'.$module.'\controller\\'.$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);
    }
}
$queryStr = $_SERVER['QUERY_STRING'];
$config = require __DIR__ . '/config.php';
$route = new Route($config['route']);
$route->parse($queryStr)->dispatch();


批改老师:韦小宝批改时间:2018-12-18 11:51:47
老师总结:写的很不错!注释的也很清晰!课后记得要多多练习哦!

发布手记

热门词条