摘要:<?php /** * 路由解析类 * 1.路由解析 * 2.请求分发 */ namespace pig; class Route { //路由配置参数 protected $rout
<?php
/**
* 路由解析类
* 1.路由解析
* 2.请求分发
*/
namespace pig;
class Route
{
//路由配置参数
protected $route = [];
//PATHINFO解析模块
protected $pathInfo = [];
//为了测试把私有属性protected修改成public
// public $pathInfo = [];
//URL参数数组
protected $params = [];
// public $params = [];
//构造方法
public function __construct($route)
{
//用路由配置初始化
$this->route = $route;
}
//解析路由
public function parse($queryStr='')
{
// /admin/user/add/name/zhu/age/30
// 解析模块:$this->pathInfo =['module'=>'admin','controller'=>'user','action'==>'add']
// 参数数组:$this->params = ['name'=>'zhu','age'=>30]
//第一步:将字符串前后的/去掉,再按分隔符/拆分到数组中
// http://pig.io/pig/route.php?admin/user/add/name/zhu/age/30 结果: /admin/user/add/name/zhu/age/30
//1.strtolower($queryStr)转换成小写,trim去掉前后/
//$queryStr = trim(strtolower($queryStr),'/');
$queryStr = trim(strtolower($queryStr),'/');
//2.用explode('/',$queryStr)切割
$queryArr= explode('/',$queryStr);
//3.用array_filter()过滤空值,0会当成false
//$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数组的索引开始,将剩余的元素全部作为参数来处理
$arr = array_slice($queryArr,3);
//从第4个元素进行处理,键值对必须成对出现,每次递增2,每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 dispatch()
{
//生成的带有命名空间的控制器类名称:app\模块\controller\控制器类
//类名称与类文件所在的绝对路劲一一对应,实现自动映射,方便加载
//模块名称
$module = $this->pathInfo['module'];
//控制器名称 获取绝对路径:'app\\' . $module .'\controller\\' .
$controller = 'app\\' . $module .'\controller\\' . ucfirst($this->pathInfo['controller']);
//die($controller);
//操作名
$action = $this->pathInfo['action'];
//判断$controller是否存在$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\\';
}
}
//测试路由
$queryStr = $_SERVER['QUERY_STRING'];
echo $queryStr;
echo '<hr>';
echo '<pre>';
print_r(explode('/',$queryStr));
echo '<hr>';
$config = require 'config.php';
//实例化Route(),放在变量中
$route = new Route($config['route']);
$route->parse($queryStr);
//显示模块/控制器/方法
print_r($route->pathInfo);
//显示参数
print_r($route->params);
//对象的形式调用
//print_r($route->parse());
//测试请求分发
require __DIR__ .'/../app/admin/controller/Index.php';
echo $route->dispatch();
批改老师:天蓬老师批改时间:2019-04-08 10:12:46
老师总结:你这是把教学代码全部复制上来, 真的懂了吗