如何實現一個php框架系列文章【4】url路由管理

直接經過url參數訪問業務模塊($app)中控制器($ctl)裏的函數($act)

 

咱們支持3種路由模式php

    普通模式  html

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

        最簡單的方式,專一實現業務$act函數,不須要再寫額外代碼nginx

        爲何參數名前面要加下劃線就不解釋了web

          

 

    easy模式apache

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

        _easy=$app.$ctl.$actapp

        在web開發中,一般咱們在$act中輸出一個前端頁面,函數

        easy模式下,若是未實現$act處理函數,會自動尋找並顯示對應的前端模板文件。ui

        對於簡單的展現頁面適合使用這種路由模式

        

        

   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 ;
         }     
     }
相關文章
相關標籤/搜索