•  

【20201026】做个web框架(3)——路由Router(三)请求资源路径映射处理程序

发表于 2020-10-26,阅读 19

介绍

介绍

童鞋们今天福哥就要带着大家完成路由对象TFRouter的功能了,首先福哥和大家先想一想如何映射才能起到安全又灵活的双重目的。

第一点:既然要安全就是不能直接通过浏览器就可以访问到,这里面就必须借助路由的基本功能将非法请求进行一个屏蔽处理。

第二点:除了安全还需要灵活,灵活就是高度的自由,也就是说我们不能对项目开发人员进行过多的限制,这里面福哥想到的是路径里面的特殊字符是需要屏蔽掉的,其他方面暂时不需要做过多考虑。

TFRouter

我们打开System/TFRouter.inc.php程序文件,建立TFRouter对象。福哥给出了TFRouter对象的主要方法的示例代码,后面会给大家讲解。

getUri

private function getUri($uri){
    if($uri == ""
        || substr($uri, -1) == "/"){
        $uri .= "index";
    }

    return $uri;
}

parseUri

private function parseUri($uri){
    if(preg_match("/\.([^\.]+)\$/", $uri, $rg)){
        $uri = substr($this->uri, 0, strlen($uri)-strlen($rg[0]));
        $this->extension = strtolower($rg[1]);
    }

    return $uri;
}

detectMapping

private function detectMapping($uri){
    // direct mapping
    $ctrlRootDirPath = $this->webInfDir. "Controller";
    $ctrlFilePath = $ctrlRootDirPath. "/". $uri. ".inc.php";
    if(file_exists($ctrlFilePath)){
        $this->mappingMethod = "direct";
        $mapped = true;
    }
    else{
        // manual mapping
        $mapped = false;
        $ctrlDirPath = dirname($ctrlFilePath);
        while(true){
            $ctrlFilePath = $ctrlDirPath. "/.mapping.inc.php";
            if(file_exists($ctrlFilePath)){
                $this->mappingMethod = "manual";
                $mapped = true;
                break;
            }
            else if($ctrlDirPath == $ctrlRootDirPath){
                break;
            }
            $ctrlDirPath = dirname($ctrlDirPath);
        }
    }

    // result
    if($mapped){

        return $ctrlFilePath;
    }

    return null;
}

map

private function map($uri){
    // parse uri
    $uri = $this->getUri($uri);
    $uri = $this->parseUri($uri);

    // mapping
    $mappingFilePath = $this->detectMapping($uri);

    // debug
    if($mappingFilePath != null){
        echo ("<li>[". $this->mappingMethod. "] ok of ". $this->uri);
        echo ("<li>". $mappingFilePath);
    }
    else{
        echo ("<li>[missing] 404 of ". $this->uri);
    }
}

TFRouteMap

我们打开TFRouteMap.php程序文件,在里面调用TFRouter对象,实现路由功能。

use TFPHP\System\TFRouter;

include_once ('./System/TFRouter.inc.php');

new TFRouter(
    __DIR__. "/WEB-INF/",
    $_SERVER['QUERY_STRING']
);

讲解

TFRouter

福哥来讲解一下TFRouter路由对象的逻辑,首先福哥没有给出构造器的代码,在构造器里面会调用map方法进行资源路径的映射操作。

getUri

该方法判断如果用户请求的资源路径是一个目录而不是一个具体的文件名的话,我们就默认寻找“index”这个文件名。

parseUri

该方法用来解析请求的资源路径包括的扩展名等等信息,这里只是提取了扩展名,后面大家可以解析资源路径的更多信息出来。

detectMapping

这个方法是资源路径映射的核心方法,首先通过直接(direct)方法进行映射探测,如果直接映射成功就返回了。否则就进行手动(manual)方法进行映射探测,而且是一级一级地向上翻,直到找到可以成功实现手动方法映射的文件(.mapping.inc.php)为止。

map

这个方法是入口方法,用来将资源路径映射操作串起来,实现路由的基本功能。

TFRouteMap

这个TFRouteMap.php是我们通过rewrite重写将所有访问都引入到这个文件里面的,这个文件会引用System/TFRouter对象,然后初始化TFRouter对象,并传入“WEB-INF”绝对路径和环境变量QUERY_STRING(也就是rewrite引入的原请求资源路径),这样TFRouter就会对原请求资源路径按照我们设想的那样进行映射处理了。

测试

下面我们来测试一下路由模块的工作是否正常,分为两个模式:direct(直接映射)、manual(手动映射)。

http://192.168.1.168:8068/

90806263b2d7b2c6.jpg

http://192.168.1.168:8068/aboutus

c9fd6d1917cb5d6f.jpg

http://192.168.1.168:8068/products/tfapp

fb2ac38a8e1e9fd1.jpg

http://192.168.1.168:8068/download/tfapp/v1.0.0/tfapp-v1.0.0.zip

baa9761e21689eab.jpg

总结

福哥今天带着大家实现了路由模块TFRouter对象的基本功能,可以对任意访问请求的资源路径进行自动的映射了。但是,目前这个路由模块还是很简单的,没有考虑太多的因素,也没有提取足够多的环境信息,真正投入生产环境的时候,这样的路由模块是无法满足需要的,那么福哥会在后面将完善后的路由模块随着正式版本TFPHP一起发布出来的,敬请期待吧~~

下一课福哥会带着童鞋们开始了解控制器模块TFController的设计了,控制器模块涉及到的内容比较多,大家要跟上福哥哦~~

P.S.

微信公众号的文章发出去之后是不能编辑的,但是福哥偶尔会修复一些描述不到位、示例不正确、结构不清晰等等的文章错误,这些只能在网站上才能看到最新版本内容,望大家知晓~~


鬼谷子叔叔
  • 日志:212
  • 回复:13

进入ta的主页