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的类和方法