zoukankan      html  css  js  c++  java
  • 如何实现一个php框架系列文章【4】url路由管理

    直接通过url参数访问业务模块($app)中控制器($ctl)里的函数($act)

    我们支持3种路由模式

        普通模式  

            _a=$app,     _u=$ctl.$act        

            最简单的方式,专注实现业务$act函数,不需要再写额外代码

            为什么参数名前面要加下划线就不解释了

              

     

        easy模式

            _easy=$app.$tpl.$ctl.$act

            _easy=$app.$ctl.$act

            在web开发中,通常我们在$act中输出一个前端页面,

            easy模式下,如果未实现$act处理函数,会自动寻找并显示对应的前端模板文件。

            对于简单的展示页面适合使用这种路由模式

            

            

       url重写模式(需要nginx或apache配置)         

            apache: ^rewrite[./](.*)$ /index.php?_rewrite=$1  [R,QSA]

            nginx:  rewrite ^/rewrite[./](.*)$ /index.php?_rewrite=$1 last;

     

            rewrite.{$app}.{$ctl}.{$act}.{$params}.html

            或更加优雅的目录式访问方式

            rewrite/{$app}/{$ctl}/{$act}/{$params}.html

     

            其中$params为选填参数部分.格式为urlencode后的参数列表    

            如果想传递sp_uid=1&d=1.2&p=sb, 那么$params = sp_uid%3D1%26d%3D1.2%26p%3Ds%2Fb

            或sp_uid/1/d/1.2/p/sb 

           

             在某些要求url中不能带?&特殊字符的场景下可以使用这种模式

            1. 为了能通过qq oauth2登陆验证,需要配置重写规则

                rewrite.thirdlogin.index.qqcallback.sp_uid%3D1.php

            2. 资源静态化

                rewrite.upload.index.out.uidm%3D310ef4b.png

            3. 支付回调

                rewrite.pay.weixin.native2_notify.php

            4. 微信开放平台授权回调

                rewrite/web/component/message/_app_id/xxxxxxx.php

     

     

    部分实现代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        $a = (!empty($_REQUEST['_a']) && is_string($_REQUEST['_a'])) ? $_REQUEST['_a'] : 'web';
        if (!preg_match('/^[w.]+$/'$a)) {
            exit('invalid _app name! ' . htmlspecialchars($a));
        }   
        $GLOBALS['_UCT']['APP'] = !empty($a) ? strtolower($a) : 'web';
            
        $u = (!empty($_REQUEST['_u']) && is_string($_REQUEST['_u'])) ? $_REQUEST['_u'] : 'index.index';
        if (!preg_match('/^[w.]+$/'$u)) {
            exit('invalid _url name! ' . htmlspecialchars($u));
        }   
        $u                      explode('.'$u, 2); 
        $GLOBALS['_UCT']['CTL'] = !empty($u['0']) ? strtolower($u['0']) : 'index';
        $GLOBALS['_UCT']['ACT'] = !empty($u['1']) ? strtolower($u['1']) : 'index';

     

    easy模式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
        //easy 模式直接访问模板tpl
        if (!empty($_REQUEST['_easy']) && is_string($_REQUEST['_easy'])) {
            $easy explode('.'$_REQUEST['_easy']);
            switch (count($easy)) {
                case 4:
                    $_GET['_u'] = $_REQUEST['_u'] = $easy[2] . '.' $easy[3];
                    if (preg_match('/^[w.]+$/'$easy[1])) {
                        $GLOBALS['_UCT']['TPL'] = $easy[1];
                    }
                    $_GET['_a'] = $_REQUEST['_a'] = $easy[0];
                    break;
                case 3:
                    $_GET['_u'] = $_REQUEST['_u'] = $easy[1] . '.' $easy[2];
                    $_GET['_a'] = $_REQUEST['_a'] = $easy[0];
                    break;
                case 2:
                    $_GET['_u'] = $_REQUEST['_u'] = $easy[1];
                    $_GET['_a'] = $_REQUEST['_a'] = $easy[0];
                    break;
                case 1:
                    $_GET['_a'] = $_REQUEST['_a'] = $easy[0];
                    break;
                default:
                    exit('invalid _easy param! ' . htmlspecialchars($_REQUEST['_easy']));
            }
        }

     

    rewrite模式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
        //url重写模式
        if (!empty($_REQUEST['_rewrite']) && is_string($_REQUEST['_rewrite'])) {
            //1.支持apache 重写模式下?后的参数缺失的情况 
            if(stripos($_SERVER['SERVER_SOFTWARE'], 'nginx') === false) {
                $_REQUEST['_rewrite'] = urldecode(substr($_SERVER['QUERY_STRING'], strlen('_rewrite=')));
            }
            //2. 丢弃_rewrite中的后缀名
            $rewrite substr($_REQUEST['_rewrite'], 0, strrpos($_REQUEST['_rewrite'], '.'));
     
            //3. 支持/作为分隔符
            $sp '.';
            for($i = 0; $i strlen($rewrite); $i++) {
                if(in_array($rewrite[$i], array('.''/'))) {
                    $sp $rewrite[$i];
                    break;
                }
            }
            $rewrite explode($sp$rewrite, 4);
            //最后1段是必填后缀名
            switch(count($rewrite)) {
                case 3:
                case 4: {
                    $_GET['_a'] = $_REQUEST['_a'] = $rewrite[0];
                    $_GET['_u'] = $_REQUEST['_u'] = $rewrite[1].'.'.$rewrite[2];
                    if(!empty($rewrite[3])) {
                        if(strpos($rewrite[3], '/')) {
                            $params explode('/'$rewrite[3]);
                            for($i=0; $i+1<count($params); $i+=2) {
                                $_REQUEST[urldecode($params[$i])] = urldecode($params[$i+1]);
                            }   
                        }   
                        else {
                            foreach(explode('&'$rewrite[3]) as $p) {
                                list($k$v) = explode('='$p, 2);  
                                $_REQUEST[urldecode($k)] = urldecode($v);
                            }   
                        }   
                    }   
                    break;
                }   
                case 2:
                    $_GET['_a'] = $_REQUEST['_a'] = $rewrite[0];
                    $_GET['_u'] = $_REQUEST['_u'] = $rewrite[1];
                    break;
                case 1: 
                    $_GET['_a'] = $_REQUEST['_a'] = $rewrite[0];
                    break;
                default:
                    break;
            }     
        }

     

  • 相关阅读:
    记录--部分sql函数、...
    记录--keep-alive实现路由页面缓存
    记录--JS隐式类型计算
    Node.js 安装及环境配置 以及google浏览器安装插件并使用
    Windows系统下PHP使用Redis
    linux常用命令全集
    LEMP--如何在Ubuntu上安装Linux、Nginx、MySQL和PHP
    进制的表现形式
    使用拆分组合法进行二进制与八进制,十六进制的相互转换
    使用8421码进行二进制与十进制的相互转换
  • 原文地址:https://www.cnblogs.com/yyluming/p/5192156.html
Copyright © 2011-2022 走看看