zoukankan      html  css  js  c++  java
  • zpf 路由功能

    2015-4-11 20:51:06

    又搞了一天, 解决了一堆bug, 重新规划了类文件夹, 改善自动加载功能

    最新的特性就是支持子域名路由了

    因为整个框架还在完善当中, 而且里边有好多接口有我自己申请的第三方appkey 和 secretkey, 所以还不方便提供下载

    但是路由功能完成以后,整体的框架也就快完工了, 再修修补补就行了

    四年啦, 从零开始, 终于有模有样了....

    比如: 

    访问 www.zhangzhibin.com 是会跳转到网站首页的

    访问 www.zhangzhibin.com/bbs 是会跳转到bbs论坛页面

    但是我想在访问 love.zhangzhibin.com时也跳转到bbs论坛页面 (因为在大众点评留下的开发者信息是love.zhangzhibin.com)

    此时可以在路由文件中设置一个对应关系就可以了(第8行):

     1 public function setRoute()
     2     {
     3         $this->route_config = array(
     4             'subdomain' => array(),
     5             'uri' => array()
     6         );
     7 
     8         //================子域名路由
     9         $this->route_config['subdomain']['#love_(d)_([a-z])#'] = 'test/index/safe/$1/$2';
    10         $this->route_config['subdomain']['#love_(d)#'] = 'test/index/safe/$1';
    11         $this->route_config['subdomain']['#love#'] = 'bbs/index/index';
    12 
    13 
    14         //================ uri路由
    15         $this->route_config['uri']['#([a-z]+)_(d+).html#'] = 'test/index/testroute/$1/$2';
    16         $this->route_config['uri']['#map.html#'] = 'map/index/line';
    17     }

    测试结果:

     1  2  3 
     4 http://love_1.zhangzhibin.com/
     5 Array
     6 (
     7     [$1] => 1
     8 )
     9 
    10 http://love_1_a.zhangzhibin.com/
    11 Array
    12 (
    13     [$1] => 1
    14     [$2] => a
    15 )

    注意, 这里的路由项的键两边有两个'#'做为边界符是需要自己去写的, 如果担心冲突, 大家可以根据需要自己去设定边界符

    整体的逻辑是这样的

    先匹配子域名的路由, 然后匹配uri的路由(不匹配?后边的查询串)

    将两步匹配到的参数合并起来, 因为uri在第二步匹配, 所以uri的匹配结果会覆盖掉子域名的路由结果

    下边贴出代码: 

      1 <?php
      2 class Route
      3 {
      4     public $subdomain = '';
      5     public $uri = '';
      6 
      7     public $ismatch = false;
      8     public $DomainMatchName = false;
      9     public $UriMatchName = false;
     10     public $MatchName = false;
     11 
     12     public $module = 'index';
     13     public $controller = 'index';
     14     public $action = 'index';
     15 
     16     public $args = array();
     17 
     18     public $error = '';
     19     
     20     public $route_config = array(
     21             'subdomain' => array(),
     22             'uri' => array()
     23         );    
     24 
     25 
     26     public function __construct($subdomain, $uri)
     27     {
     28         $this->subdomain = $subdomain;
     29         $this->uri = $uri;
     30 
     31         //设置路由配置信息
     32         $this->setRoute();
     33 
     34         //先检查子域名路由
     35         //如果子域名中只有英文字母就不再匹配
     36         if (!empty($this->route_config['subdomain']) || !ctype_alpha($this->subdomain)) {
     37             $this->DomainMatchName = $this->preg_parse($this->route_config['subdomain'], $this->subdomain);
     38         }
     39 
     40         //再检查uri路由
     41         //如果uri中不含有"/"才会走正则匹配
     42         if (!empty($this->route_config['uri']) && strpos($this->uri, '/') === false) {
     43             $this->UriMatchName = $this->preg_parse($this->route_config['uri'], $this->uri);
     44         } else {
     45             $this->arr_parse();
     46         }
     47 
     48         ($this->DomainMatchName || $this->UriMatchName) && ($this->ismatch = true);
     49 
     50         $this->MatchName = $this->UriMatchName ? $this->UriMatchName : $this->DomainMatchName;
     51 
     52         return $this;
     53     }
     54 
     55     public function setRoute()
     56     {
     57         //================子域名路由
     58         $this->route_config['subdomain']['#love_(d)_([a-z])#'] = 'test/index/safe/$1/$2';
     59         $this->route_config['subdomain']['#love_(d)#'] = 'test/index/safe/$1';
     60         $this->route_config['subdomain']['#love#'] = 'bbs/index/index';
     61 
     62         //================ uri路由
     63         $this->route_config['uri']['#svnsort#'] = 'index/index/svnsort';
     64         $this->route_config['uri']['#nicename_json#'] = 'index/index/nicenamejson';
     65         $this->route_config['uri']['#nicename#'] = 'index/index/nicename';
     66         $this->route_config['uri']['#test[^/]#'] = 'test/index/rtest'; //是下边路由的前缀, 加上就是全词匹配了
     67         $this->route_config['uri']['#test1#'] = 'test/index/rtest'; // 不会匹配test, 只会匹配test1
     68 
     69     }
     70 
     71     //正则匹配分析
     72     public function preg_parse($routeconfig, $subject)
     73     {
     74         $routename = false;
     75         foreach ($routeconfig as $pattern => $route) {
     76             $arrRoute = explode('/', $route);
     77             
     78             preg_match($pattern, $subject, $matches);
     79 
     80             if (empty($matches)) {
     81                 continue;
     82             } else {
     83                 $routename = $pattern;
     84 
     85                 $arrMCA = array_slice($arrRoute, 0, 3);
     86                 $arrArg = array_slice($arrRoute, 3);
     87 
     88                 $this->module = $arrMCA[0];
     89                 $this->controller = $arrMCA[1];
     90                 $this->action = $arrMCA[2];
     91 
     92                 $arrMatchArg = array();
     93                 foreach ($matches as $key => $value) {
     94                     $arrMatchArg['$'.$key] = $value;
     95                 }
     96 
     97                 foreach ($arrArg as $value) {
     98                     $this->args[$value] = $arrMatchArg[$value];
     99                 }
    100 
    101                 break;
    102             }
    103         }
    104 
    105         return $routename;
    106     }
    107 
    108     //正则检查uri没有匹配上的情况下, 数组匹配分析
    109     public function arr_parse()
    110     {
    111         //获得module/controller/action
    112         $arrPathInfo = explode('/', $this->uri);//存放URL中以正斜线隔开的内容的数组
    113         
    114         !empty($arrPathInfo[0]) && ($this->module = $arrPathInfo[0]);
    115         !empty($arrPathInfo[1]) && ($this->controller = $arrPathInfo[1]);
    116         !empty($arrPathInfo[2]) && ($this->action = $arrPathInfo[2]);
    117         
    118         //存放除module/controller/action之外的参数
    119         // /a/1/b/2/c/3 ==> ?a=1&b=2&c=3
    120         // 当键和值不成对出现时,默认最后一个键的值为0
    121         // 参数中不要出现数字键,否则在合并post,get参数时会出错
    122         $intPathInfo = count($arrPathInfo);
    123         if ($intPathInfo > 3) {
    124             $arrPath = array_slice($arrPathInfo, 3);
    125             $intArgNum = count($arrPath);
    126             if ($intArgNum % 2 != 0) {
    127                 $arrPath[] = 0;
    128             }
    129             $intArgNum = count($arrPath);
    130 
    131             for ($i=0; $i<$intArgNum; $i=$i+2) {
    132                 $this->args[$arrPath[$i]] = $arrPath[$i+1];
    133             }
    134         }
    135     }
    136 }

     当然你也可以写自己的路由类, 只需要返回给框架所需要的数据就行啦~

     1     //可以自己实现路由类, 只要要返回 module, controller, action, 以及匹配到的参数就行了
     2     //返回是否匹配了路由, 匹配路由的名字, 路由指向的module,controller,action, 路由错误信息,方便调试
     3     public function route()
     4     {
     5         $this->route = new Route($this->subdomain, $this->document_uri);
     6         
     7         $this->isRouteMatch = $this->route->ismatch;
     8         $this->RouteMatchName = $this->route->MatchName;
     9 
    10         $this->module = $this->route->module;
    11         $this->controller = $this->route->controller;
    12         $this->action = $this->route->action;
    13 
    14         $this->setData();
    15     }
  • 相关阅读:

    bzoj3052: [wc2013]糖果公园
    莫队算法心得
    bzoj1104: [POI2007]洪水pow
    bzoj1102: [POI2007]山峰和山谷Grz
    bzoj1121: [POI2008]激光发射器SZK
    bzoj1113: [Poi2008]海报PLA
    bzoj1103: [POI2007]大都市meg
    bzoj1396: 识别子串
    bzoj3756: Pty的字符串
  • 原文地址:https://www.cnblogs.com/iLoveMyD/p/4418417.html
Copyright © 2011-2022 走看看