路由解析+请求分发

Original 2019-03-03 17:09:56 557
abstract:/*** 配置文件Config.php*/<?php/** * 配置文件:适用于整个应用 * 采用php数组的方式返回数据 */return [    //应用配置    'app' => [        //调试开关        

/**
* 配置文件Config.php
*/

<?php
/**
* 配置文件:适用于整个应用
* 采用php数组的方式返回数据
*/
return [
   //应用配置
   'app' => [
       //调试开关
       'debug' => true,
   ],

   //路由配置
   'route' => [
       //默认模块
       'model' => 'admin',

       //默认控制器
       'controller' => 'Index',

       //默认操作
       'action' => 'index',
   ],

   //数据库配置
   'db' => [
       //数据库类型
       'database_type' => 'mysql',

       //默认的数据库名称
       'database_name' => 'frame',

       //默认主机名
       'server' => '127.0.0.1',

       //默认的用户名
       'username' => 'root',

       //用户密码
       'password' => 'root',

       //默认客户端的字符编码集
       'charset' => 'utf8',

       //默认服务端口号
       'port' => 3306,
   ],
];

?>


/**
* 路由解析类Route.php
* 1.路由解析
* 2.请求分发
*/

<?php

namespace config;

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

   //PATHINFO
   protected $pathInfo = [];

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

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

   //解析路由:将url解析到对应的模块,控制器和操作
   public function parse($queryStr='')
   {
       //  /admin/user/add/name/lee/age/30
       //  $this->pathinfo = ['module'=>'admin','controller'=>'user','action'=>'add']
       //  参数数组:$this->paras = ['name'=>'lee','age'=>30]

       //第一步:将查询字符串前后的/去掉,再按分隔符/拆分到数组中
       $queryStr = trim(strtolower($queryStr),'/');
       $queryArr = explode('/',$queryStr);//explode():把字符串打散为数组
//        $queryArr = array_filter($queryArr);//array_filter过滤数组中为空的值

       //第二部:解析出$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()
       return $this;

   }

   //请求分发
   public function disspatch()
   {
       //生成的带有命名空间的控制器类名称: app\模块\controller\控制器类
       //类名称应该与类文件所在的绝对路径一一对应,这样才可以实现自动映射,方便自动加载
       //模块名称
       $module = $this->pathInfo['module'];

       //控制器
       $controller = 'app\\' . $module . '\controller\\'. ucfirst($this->pathInfo['controller']);
//        die($controller);

       //操作名
       $action = $this->pathInfo['action'];
       //method_exists检查类的方法是否存在
       if(!method_exists($controller,$action)){
           $action = $this->route['action'];
//            header('Location:/');
           return '不存在该操作';
       }

       //将用户的请求分发到指定的控制器和对应的操作方法上
       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']);
   }

   //获得参数
   public function getParams()
   {
       return $this->params;
   }
}

?>

Correcting teacher:西门大官人Correction time:2019-03-03 17:31:49
Teacher's summary:路由解析是mvc框架中比较核心的步骤。目的是把用户的url请求解析映射为类和方法

Release Notes

Popular Entries