当前位置:Gxlcms > PHP教程 > 如何实现一个php框架系列文章【4】url路由管理

如何实现一个php框架系列文章【4】url路由管理

时间:2021-07-01 10:21:17 帮助过:18人阅读

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

}

}

人气教程排行