博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
thinkphp 路由规则终极详解(附伪静态)
阅读量:6607 次
发布时间:2019-06-24

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

hot3.png

'news/read?year=:2&month=:3&day=:4', 'news/:action^delete|update|insert/:year\d/:month/:day'=>array(                'news/read?extra=:2&status=1','year=:2&month=:3&day=:4'),     );$url  = 'http://www.test.com/index.php/news/read/2012/2/21/extraparam/test.html';//后缀名$extension = 'html';//根据pathinfo定义  详情: http://my.oschina.net/u/1178986/blog/201206//可知: $_SERVER['PATH_INFO'] = 'news/read/2012/2/21/extraparam/test.html';$regx = 'news/read/2012/2/21/extraparam/test.html';//循环匹配路由规则foreach($route as $key=>$value){ //如果匹配成功,则不继续匹配 if(parseUrlRule($key,$value,$regx,$extension)) break;}//运行结果: 打印$_GET//Array//  (//      [actionName] => read//      [moduleName] => news//      [extra] => 2012//      [status] => 1//      [extraparam] => test//      [year] => 2012//      [month] => 2//      [day] => 21//      [finalUrl] => news/read?extra=2012&status=1&extraparam=test&year=2012&month=2&day=21//  )//  [Finished in 0.6s]//相当于访问: http://www.test.com/news/read?extra=2012&status=1&extraparam=test&year=2012&month=2&day=21//在部署时会把index.php隐藏,开启apache的重写模块//重写规则 : RewriteRule  ^(.+)$  /index.php/$1 //详细配置: http://lamp.linux.gov.cn/Apache/ApacheMenu/rewrite///开启后,apache会自动把 http:/www.test.com/news/read/2012/2/21/extraparam/test.html转换为 http:/www.test.com/index.php/news/read/2012/2/21/extraparam/test.html/** *  @$rule  string    路由规则    *  @$route string    规则映射的新地址 *  @$regx  string    地址栏pathinfo字符串 *  @$extension stirng  伪静态拓展名 *  return  bool  */function parseUrlRule($rule,$route,$regx,$extension=null){  //去掉后缀名  !is_null($extension) && $regx = str_replace('.'.$extension,'',$regx);  //把路由规则和地址,分割到数组中,然后逐项匹配  $ruleArr = explode('/',$rule);  $regxArr = explode('/',$regx);  //$route以数组的格式传递,则取第一个  $url = is_array($route) ? $route[0] : $route;  $match =true;  //匹配检测  foreach($ruleArr as $key=>$value){   if(strpos($value,':')===0){   if(substr($value,-2)=='\\d' && !is_numeric($regxArr[$key])){   $match = false;   break;   }elseif(strpos($value,'^')){   $stripArr = explode('|',trim(strstr($value,'^'),'^'));   if(in_array($regxArr[$key],$stripArr)){   $match = false;   break;   }   }   //静态项不区分大小写   }elseif(strcasecmp($value, $regxArr[$key])!==0) {   $match = false;   break;   }  }  //匹配成功  if($match){   //把动态变量写入到数组$matches 中,同时去除静态匹配项   foreach($ruleArr as $key=>$value){   if(strpos($value,':')===0){   //获取动态变量,作为数组下标   if(substr($value,-2,1)=='\\')   $matchKey = substr($value,1,-2);   elseif($pos=strpos($value,'^'))   $matchKey =substr($value,1,$pos-1);    else   $matchKey = substr($value,1);   $matches[$matchKey] = array_shift($regxArr);   }else   array_shift($regxArr);   //去除静态匹配项   }   //获取数组中的值,目的是配合子模式进行替换   $values = array_values($matches);   //正则匹配替换,正则需要用'e'作为修饰符   $url = preg_replace('/:(\d+)/e','$values[\\1-1]',$url);   //解析url    格式:  分组/模块/操作?key1=value1&key2=value2   if(strpos($url,'?')!==false){       // 分组/模块/操作?key1=value1&key2=value2   $arr = parse_url($url);   $paths = explode('/',$arr['path']);   parse_str($arr['query'],$queryArr);   }elseif(strpos($url,'/')!==false)  //分组/模块/操作)   $paths = explode('/',$url);   else  // key1=value1&key2=value2   parse_str($url,$queryArr);   //获取 分组 模块 操作   if(!empty($paths)){   $var['actionName'] = array_pop($paths);   $var['moduleName'] = array_pop($paths);   if(!empty($paths)){   $groupList = 'Home,Admin';   $temp = array_pop($paths);   if(in_array($temp,explode(',',$groupList)))   $var['groupName'] = $temp;   }   }   //合并的到GET数组中,方便全局调用   $_GET = array_merge($_GET,$var);   //合并参数   if(isset($queryArr))   $_GET = array_merge($_GET,$queryArr);   //匹配url中剩余的参数   preg_replace('/(\w+)\/([^,\/]+)/e','$tempArr[\'\\1\']=\'\\2\'',implode('/',$regxArr));   if(!empty($tempArr))   $_GET = array_merge($_GET,$tempArr);   //route是数组的话   if(is_array($route)){   $route[1]=preg_replace('/:(\d+)/e','$values[\\1-1]',$route[1]);   parse_str($route[1],$var);   $_GET = array_merge($_GET,$var);   strpos($url,'?')!==false ? $der ='&' : $der='?';   //最终写入到$_GET中的参数,包括三个部分   //1.地址栏剩余参数   //2.路由地址中的参数   //3.$route是数组时的第二个参数   if(!empty($tempArr))   $var = array_merge($tempArr,$var);   $url .=$der.http_build_query($var);   }   $_GET['finalUrl'] = $url;   //保证$_REQUEST 也能访问   $_REQUEST = array_merge($_REQUEST,$_GET);   //结果   print_r($_GET);   return true;  }  return $match;}//以下是正则路由代码: $rule = '/news\/read\/(\d+)\/(\d+)\/(\d+)/';$route ='news/read?year=:1&month=:2&day=:3';$regx = 'news/read/2012/2/21/extraparam/test.html';$extension = 'html';parseUrlRuleRegx($rule,$route,$regx,$extension);/** *  @$rule  string    路由规则    *  @$route string    规则映射的新地址 *  @$regx  string    地址栏pathinfo字符串 *  @$extension stirng  伪静态拓展名 *  return  bool  */function parseUrlRuleRegx($rule,$route,$regx,$extension=null){  !is_null($extension) && $regx = str_replace('.'.$extension,'',$regx);  $url = is_array($route) ? $route[0] : $route;  if(preg_match($rule,$regx,$matches)){   $url = preg_replace('/:(\d+)/e','$matches[\\1]',$url);  }else      return false;  //解析url    格式:  分组/模块/操作?key1=value1&key2=value2  if(strpos($url,'?')!==false){      // 分组/模块/操作?key1=value1&key2=value2  $arr = parse_url($url);  $paths = explode('/',$arr['path']);  parse_str($arr['query'],$queryArr);  }elseif(strpos($url,'/')!==false)  //分组/模块/操作)  $paths = explode('/',$url);  else  // key1=value1&key2=value2  parse_str($url,$queryArr);  //获取 分组 模块 操作  if(!empty($paths)){  $var['actionName'] = array_pop($paths);  $var['moduleName'] = array_pop($paths);  if(!empty($paths)){  $groupList = 'Home,Admin';  $temp = array_pop($paths);  if(in_array($temp,explode(',',$groupList)))  $var['groupName'] = $temp;  }  }  //合并的到GET数组中,方便全局调用  $_GET = array_merge($_GET,$var);  if(isset($queryArr))  $_GET = array_merge($_GET,$queryArr);  //匹配剩余的参数  $regx = str_replace($matches[0],'',$regx);  preg_replace('/(\w+)\/([^,\/]+)/e','$tempArr[\'\\1\']=\'\\2\'',$regx);  if(!empty($tempArr)){  $_GET = array_merge($_GET,$tempArr);  strpos($url,'?')!==false ? $der='&':$der='?';  $url .=$der.http_build_query($tempArr);  }  if(is_array($route)){  $route[1] = preg_replace('/:(\d+)/e','$matches[\\1]',$route[1]);  parse_str($route[1],$var);  if(!empty($var)){  !empty($queryArr) && $var =array_merge($queryArr,$var);  $_GET= array_merge($_GET,$var);  }  strpos($url,'?')!==false ? $der='&':$der='?';  $url .=$der.http_build_query($var);  }  $_GET['finalUrl'] = $url;  print_r($_GET);  $_REQUEST = array_merge($_GET,$_REQUEST);  return true;}//运行结果: //Array// (//     [actionName] => read//     [moduleName] => news//     [year] => 2012//     [month] => 2//     [day] => 21//     [extraparam] => test//     [finalUrl] => news/read?year=2012&month=2&day=21&extraparam=test// )// [Finished in 0.1s]

转载于:https://my.oschina.net/u/1178986/blog/201710

你可能感兴趣的文章
2018.10.27-dtoj-3996-Lesson5!(johnny)
查看>>
DataTable转换成json字符串
查看>>
ubuntu 12.04 安装 redis
查看>>
Sql Server中不常用的表运算符之APPLY(1)
查看>>
【DM642】ICELL Interface—Cells as Algorithm Containers
查看>>
linux所有命令失效的解决办法
查看>>
力扣算法题—085最大矩阵
查看>>
svs 在创建的时候 上传文件夹 bin obj 这些不要提交
查看>>
mysql-用命令导出、导入表结构或数据
查看>>
Tinkphp
查看>>
EntityFrameworkCore 一对一 && 一对多 && 多对多配置
查看>>
How to temporally disable IDE tools (load manually)
查看>>
Vue.js学习 Item4 -- 数据双向绑定
查看>>
几种排序方式的java实现(01:插入排序,冒泡排序,选择排序,快速排序)
查看>>
server application unavailable
查看>>
eclipse 的小技巧
查看>>
频率域滤波
查看>>
图片存储类型的种类、特点、区别
查看>>
GETTING UP AND RUNNING WITH NODE.JS, EXPRESS, JADE, AND MONGODB
查看>>
求二叉树第K层节点的个数
查看>>