摘要:route.php <?php /** * 路由解析类 * 1.路由解析 * 2.请求分发 */ namespace pig; class Route { //路由配置信息 protected&nbs
route.php
<?php
/**
* 路由解析类
* 1.路由解析
* 2.请求分发
*/
namespace pig;
class Route
{
//路由配置信息
protected $route = [];
//PATHINFO
//public $pathInfo = [];
protected $pathInfo = [];
//URL参数
protected $params = [];
//public $params = [];
//构造方法
public function __construct($route)
{
//路由配置初始化
$this->route = $route;
}
//解析路由
public function parse($queryStr = '')
{
// /admin/user/add/name/peter/age/30
// $this->pathInfo = ['module'=>'admin','controller'=>'user','action'=>'add']
// 参数数组:$this->params = ['name'=>'peter','age'=>30]
//第一步:将查询字符串前后的/去掉,再按分隔符/拆分到数组中
$queryStr = trim(strtolower($queryStr), '/');
$queryArr = explode('/', $queryStr);
// $queryArr = array_filter($queryArr);
//第二步:解析出$queryArr数组中的内容(模块。控制器,操作,参数);
switch(count($queryArr))
{
//没有参数,则使用默认的模块、控制器、操作
case 0:
$this->pathInfo = $this->route;
break;
//只有一个参数:用户只提供了模块,控制器和操作只用默认值
case 1:
$this->pathInfo['module'] = $queryArr[0];
//二个参数:模块和控制器自定义,操作默认
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);
//print_r($arr);die;
//键值必须成对出现,所以每次递增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()====$route->parse();$route->worm();
return $this;
}
//请求分发
public function dispatch()
{
//生成带有命名空间的控制器类名称:app\模块\controller\控制器类
//类名称应该与类文件的所对应的绝对路径一一对应,这样才可以实现自动映射,
//方便自动加载
//模块名称
$module = $this->pathInfo['module'];
//控制器名称
$controller = '\app\\' . $module . '\\controller\\' . ucfirst($this->pathInfo['controller']);
//die($controller);
//操作名
$action = $this->pathInfo['action'];
//die($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 '<hr>';
$config = require 'config.php';
$route = new Route($config['route']);
$route->parse($queryStr);
//print_r($route->pathInfo);
//print_r($route->params);
//测试请求分发(空间得加载)
require __DIR__.'/../app/admin/controller/Index.php';
require __DIR__.'/../app/admin/controller/User.php';
echo $route->dispatch();控制器类:
<?php
/**
* 要加载的控制器类
*/
namespace app\admin\controller;
class User
{
public function show()
{
echo '我是user控制器中的show方法';
}
}总结:路由解析类实现路由解析和请求分发,路由解析就是从url请求中的提取出模块,控制器,方法以及参数,分别存放在数组中,请求分发实现将提取的信息与路径一一对应,实现自动映射,也即将信息组装成可以访问的地址。注意,要实现自动加载,必须首先加载访问的命名空间。
运行结果:

批改老师:韦小宝批改时间:2019-02-11 10:00:22
老师总结:写的很不错 路由在一个框架中起到很大的一个重要 它关系到我们框架的安全性等