返回 理解自动映射和...... 登陆

理解自动映射和自动加载。请求分发处理

2019-06-11 01:43:51 282
<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/6/9
 * Time: 2:18
 */
namespace pig;
use app\admin\controller\Index;

/**
 * Class router  路由解析类
 * @package pig
 * 1  路由解析    模块/控制器/操作方法/参数
 * 2  请求分发   使用命名空间 自动映射到具体的类中 ,然后将参数传进去处理  重点理解  call_user_func_array函数
 */
class router {
    // 路由信息
    public $route = [];
    //pathInfo  参数
    public  $pathInfo = [];

    // url 参 protected   继承类  自己 同一个包的类 都可访问
    //protected $params = [];
    public $params = [];
    // 构造方法
    public  function __construct($route){
        // 路由 配置初始化
        $this->route  = $route;
    }

    //  解析 路由
    public  function parse($queryStr = ''){
        // /admin/user/add/name/peter/age/30
        // ['module'=>'admin','controller'=>'user','action'=>'add']  模块,  控制器 ,  操作方法
        //  参数  ['name'=>'peter','age'=>'30']

        //第一步 去除多余字符,切割数组,过滤数组 处理逻辑  ,  将前后的/  去掉
        $queryStr = trim($queryStr,'/');
        $queryArr = explode('/',$queryStr);
        // 过滤 数组  ,过滤掉空值
        $queryArr = array_filter($queryArr);

        //第二步  根据数组  解析出的 模块 , 控制器 ,操作 , 参数
        $num = count($queryArr);
        switch($num) {
            //  没有参数 则为默认的
            case 0:
                // 则为配置信息的默认 模块, 控制器 ,操作
                $this->pathInfo = $this->route;
                break;
            // 1个参数 表示 模快
            case 1:
                $this->pathInfo['module'] = $queryArr[0];
                break;
            //  2 个参数  表示  模块  , 控制器
            case 2:
                $this->pathInfo['module'] = $queryArr[0];
                $this->pathInfo['controller'] = $queryArr[1];
                break;
            //  3 个参数  表示  模块  , 控制器 , 操作
            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];
                // 去除多余参数
                $num -= ($num - 3) % 2 == 0 ? 0 : 1;

                // 索引从3 开始
                for ($i = 3; $i < $num; $i += 2) {
                    $this->params[$queryArr[$i]] = $queryArr[$i + 1];
                }
                break;
        }
    }

    // 请求分发
    public function dispatch(){
        // 生成带有命名空间的控制器类称: app\模块\controller\控制器\action\操作方法
        //  类名称应该与类文件一一对应 , 這样方便自动映射,实现自动加载   例: 模块\admin\控制器controller\index  操作方法\add  为 index.php(控制器文件中的函数)

        // 模块名称
        $module = $this->pathInfo['module'];

        // 控制器
        $controller = 'app\\'.$module.'\controller\\'.$this->pathInfo['controller'];

        // 操作方法
        $action = $this->pathInfo['action'];

        // 检查一个类的是否存在于该方法 ,如果没有则 默认的路由
        if(!method_exists($controller,$action) ){
            $action = $this->route['action'];
            // 设置表头跳转
            echo "没有该方法,进行表头跳转";
            //header('Location:/');
            return false;
        }
        //  使用  call_user_func_array  映射  到控制器中
        return call_user_func_array([new $controller,$action],$this->params);
    }

    // 返回参数
    public function getPrams(){
        return $this->params;
    }
}

// 测试路由
$queryStr = $_SERVER['QUERY_STRING'];
echo "<h2>".$queryStr."<hr></h2><pre>";

// 加载配置信息
$config =  require __DIR__."/config.php";

$rou = new router($config['route']);

$rou->parse($queryStr);

echo "打印模快信息";
print_r($rou->pathInfo);
echo "打印参数信息";
print_r($rou->params);

// 加载模块
require __DIR__."/../app/admin/controller/index.php";

echo "<h1>控制器名称为:</h1>";
print_r($rou->dispatch());


最新手记推荐

• 用composer安装thinkphp框架的步骤 • 省市区接口说明 • 用thinkphp,后台新增栏目 • 管理员添加编辑删除 • 管理员添加编辑删除

全部回复(0)我要回复

暂无评论~
  • 取消 回复 发送
  • PHP中文网