摘要:<?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();
批改老师:西门大官人批改时间:2019-03-03 09:48:52
老师总结:路由解析在MVC框架中占有非常重要的地位。其核心思想就是把用户输入的url解析成为php的类和方法