- <?php
- //thinkphp url调度原理 ---->http://my.oschina.net/u/1178986/blog/201206
- //thinkphp 路由定义规则
- $route = array(
- 'news/:action^delete|update|insert/:year\\d/:month/:day'=>array('news/read?extra=:2&status=1','year=:2&month=:3&day=:4'),
- 'news/:action/:year\\d/:month/:day'=>'news/read?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;
- }
- /**
- * @$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;
- }
- //在部署时会把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:/ww
- //该片段来自于http://www.codesnippet.cn/detail/170320149062.html
来源: http://www.codesnippet.cn/detail/170320149062.html