最新代码请参考:http://mengkang.net/17.html
前面已经分析过ThinkSNS的路由了,我也准备copy他们的方法,把路由写在U函数里,然后跳转到nginx服务器上配置的rewrite地址上去。就是这样!
听说代码if...else嵌套太多层就是垃圾。我想我是应该想办法优化了......
nginx.conf
location / { rewrite ^/?([0-9]+)_([0-9]+).html$ /index.php?m=Blog&a=blog&id=$1&p=$2 last; rewrite ^/?aboutme.html$ /index.php?m=Blog&a=about last; rewrite ^/?notebook.html$ /index.php?m=Blog&a=index&nav=1 last; rewrite ^/?homesick.html$ /index.php?m=Blog&a=index&nav=2 last; rewrite ^/?playground.html$ /index.php?m=Blog&a=index&nav=3 last; rewrite ^/?tag_([0-9]+).html$ /index.php?m=Blog&a=index&tag=$1 last; }
route配置参数
return array( //一级路由|规则路由 'blog/blog'=>'[id]_[p].html', 'blog/about'=>'aboutme.html', //配置多级路由 'blog/index'=>array( //没传参数的情况 'null'=>'./', //规则路由 'tag'=>'tag_[tag].html', //定制路由 'nav'=>array( '1'=>'notebook.html', '2'=>'homesick.html', '3'=>'playground.html', ) ), );
/** * Url地址构造函数 * @param string $url 控制器和方法 'Blog/blog' * @param array $params array('id'=>1,'p'=>3) * @return string $real_url 伪静态地址 或者真实的$_SERVER['QUERY_STRING'] */ function U($url,$params=null){ //是否开启路由 if(ROUTE){ //TODO //路由规则里全写成小写吧 $router_key = strtolower(trim($url)); //导入路由 $router_ruler = include(dirname(__FILE__).'/route.php'); //路由命中 if(isset($router_ruler[$router_key])){ //eg $router_key = 'blog/index'; $real_url = $router_ruler[$router_key]; //至此,一级路由已经匹配完毕,下面开始匹配多级路由 //由于规定参数格式必须是数组,所以这里只存在是数组和不是数组(为空)的情况 if(is_array($params)){ //$params = array('tag'=>1); foreach($params as $k=>$v){ //判断是否为二级路由 if(is_array($real_url)){ //$real_url = array( // 'null'=>'./', // 'nav'=>array( // '1' => 'note.html', // '2' => 'home.html', // '3' => 'xxxx.html' // ), // 'tag'=>'tag_[tag].html' // ); foreach($real_url as $key => $value){ //$params = array('nav'=>1); //$value = array('1'=>'note.html','2'=>'home.html'); if(is_array($value)){ if($key == $k){ //$k = nav //$key = nav //三级路由命中 $real_url = $value[$v]; } }else{ if($key == $k){ //二级路由命中 //$value = 'tag_[tag].html'; $real_url = routeReg($value,$k,$v); } } } }else{ //$params = array('id'=>1,'p'=>2); //$real_url;//'[id]_[p].html' //'['.$k.']';//[id] $real_url = routeReg($real_url,$k,$v); } } }else{ //没传参数的情况且为多级路由 if(is_array($real_url)){ $real_url = $real_url['null']; } } }else{ $real_url = urlBuild($url,$params); } }else{ $real_url = urlBuild($url,$params); } return $real_url; } /** * 配合http_build_query实现正常的动态地址,类似于index.php?m=xxx&a=xxx&id=xxx&p=xxx * @param string $url 控制器和方法 * @param array $params 参数列表 * @return string $real_url 实际地址 */ function urlBuild($url,$params){ $url=explode('/',$url); $real_url = SITE_URL.'?m='.$url[0].'&a='.$url[1]; if($params){ if(is_array($params)){ $params = http_build_query($params); $params = urldecode($params); } $real_url .= '&'.$params; } return $real_url; } /** * @param string $routeStr url正则字符串,类似于'tag'=>'tag_[tag].html' * @param string $key url正则中的 [关键字],如上面的的tag * @param string $value 需要替换正则字符串里面的关键字的实际参数值 * @return string $url 返回最终匹配完的伪静态地址 */ function routeReg($routeStr,$key,$value){ if(strstr($routeStr,'['.$key.']')){ $url = str_replace('['.$key.']',$value,$routeStr); } //针对参数传递不完整的,比如传了id,但是没有传p(默认为第一页,所以需要给一个默认值) $url = preg_replace('/([.*?])/',1,$url); return $url; }