摘要:<?php /** * 路由解析類 * 1. 路由解析 * 2. 請(qǐng)求分發(fā) */ namespace pig; class Route { // 路由配置信息 pr
<?php /** * 路由解析類 * 1. 路由解析 * 2. 請(qǐng)求分發(fā) */ namespace pig; class Route { // 路由配置信息 protected $route = []; // PATHINFO protected $pathInfo = []; // URL參數(shù) protected $params = []; // 構(gòu)造方法 public function __construct($route) { // 路由配置初始化 $this->route = $route; } // 解析路由 public function parse($queryStr) { // ?/admin/user/add/name/leaf/age/18 // 1. 將查詢字符串前后的 / 去掉, 在按分隔符 / 拆分到數(shù)組 $queryStr = trim(strtolower($queryStr), '/'); $queryArr = explode('/', $queryStr); // 過濾空字符 // $queryArr = array_filter($queryArr); // 2. 解析出 $queryArr 中的內(nèi)容(模塊, 控制器, 操作, 參數(shù)) switch (count($queryArr)) { // 沒有參數(shù), 模塊/控制器/操作 都采用默認(rèn)值 case 0: $this->pathInfo = $this->route; break; // 一個(gè)參數(shù), 模塊自定義, 控制器/操作采用默認(rèn)值 case 1: $this->pathInfo['module'] = $queryArr[0]; break; // 兩個(gè)參數(shù), 模塊/控制器自定義, 操作采用默認(rèn)值 case 2: $this->pathInfo['module'] = $queryArr[0]; $this->pathInfo['controller'] = $queryArr[1]; break; // 三個(gè)參數(shù), 模塊/控制器/操作 全部自定義值 case 3: $this->pathInfo['module'] = $queryArr[0]; $this->pathInfo['controller'] = $queryArr[1]; $this->pathInfo['action'] = $queryArr[2]; break; // 對(duì)參數(shù)進(jìn)行處理 default: $this->pathInfo['module'] = $queryArr[0]; $this->pathInfo['controller'] = $queryArr[1]; $this->pathInfo['action'] = $queryArr[2]; // 從pathinfo數(shù)組中索引3開始,將剩余元素全部作為參數(shù)處理 $arr = array_splice($queryArr, 3); // 鍵值對(duì)必須成對(duì)出現(xiàn),所以每次遞增2 for ($i = 0; $i < count($arr); $i += 2) { // 如果沒有第二個(gè)參數(shù), 則放棄 if (isset($arr[$i + 1])) { $this->params[$arr[$i]] = $arr[$i + 1]; } } } // 返回當(dāng)前對(duì)象實(shí)例,主要方便鏈?zhǔn)秸{(diào)用 return $this; } // 請(qǐng)求分發(fā) public function dispatch() { // 生成帶有命名空間的控制器類名稱: app\模塊\controller\控制器類 // 類名稱應(yīng)與類文件所在位置一一對(duì)應(yīng), 方便自動(dòng)加載 // 模塊名稱 $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: /'); } // 將用戶的請(qǐng)求分發(fā)到指定的控制器和對(duì)應(yīng)的操作方法上 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']); } } // 測(cè)試路由 $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); // 測(cè)試請(qǐng)求分發(fā) // 先加載對(duì)應(yīng)模塊控制器類 require __DIR__ . '/../app/admin/controller/Index.php'; echo $route->dispatch();
批改老師:西門大官人批改時(shí)間:2019-03-03 09:48:52
老師總結(jié):路由解析在MVC框架中占有非常重要的地位。其核心思想就是把用戶輸入的url解析成為php的類和方法