博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何实现一个php框架系列文章【4】url路由管理
阅读量:5061 次
发布时间:2019-06-12

本文共 4154 字,大约阅读时间需要 13 分钟。

直接通过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
;
        
}     
    
}

 

转载于:https://www.cnblogs.com/yyluming/p/5192156.html

你可能感兴趣的文章
hexo个人博客添加宠物/鼠标点击效果/博客管理
查看>>
python asyncio 异步实现mongodb数据转xls文件
查看>>
关于WPF的2000件事 02--WPF界面是如何渲染的?
查看>>
单元测试、、、
查看>>
SVN使用教程总结
查看>>
JS 浏览器对象
查看>>
TestNG入门
查看>>
【ul开发攻略】HTML5/CSS3菜单代码 阴影+发光+圆角
查看>>
虚拟中没有eth0
查看>>
Unity 3D游戏开发学习路线(方法篇)
查看>>
BZOJ2049[Sdoi2008]Cave 洞穴勘测(LCT模板)
查看>>
vuex插件
查看>>
2011年12月09日
查看>>
[ZJOI2007]棋盘制作 【最大同色矩形】
查看>>
合并单元格
查看>>
swift-初探webView与JS交互
查看>>
IOS-图片操作集合
查看>>
Android bitmap图片处理
查看>>
Android应用程序进程启动过程的源代码分析
查看>>
adb logcat 命令行用法
查看>>