php里的路由的意思是
地址转发
,那么可以在生成URL的函数里传入各个参数生成一个新的的地址(而这个地址也就是伪静态地址)
先说下我的大体思路:
第一、服务器上apache或者nginx把伪静态rewrite到实际地址。
第二、在PHP生成URL地址的时候做url的规则(而这个规则就路由文件)替换。
第三、保证用户访问的一定是伪静态地址,当用户访问非伪静态地址的时候PHP端根据
$_SERVER['REQUEST_URI']
判断其是否非伪静态地址,如果不是就跳转到路由表规定的伪静态地址。
伪静态配置(nginx.conf)
路由表文件location / {rewrite ^/?([0-9]+).html$ /index.php?m=Blog&a=blog&id=$1 last;rewrite ^/?([0-9]+)-([0-9]+).html$ /index.php?m=Blog&a=blog&id=$1&p=$2 last;rewrite ^/?about.html$ /index.php?m=Blog&a=about last;rewrite ^/?tags.html$ /index.php?m=Blog&a=tags last;rewrite ^/?notebook.html$ /index.php?m=Blog&a=blogList&nav=1 last;rewrite ^/?notebook-([0-9]+).html$ /index.php?m=Blog&a=blogList&nav=1&p=$1 last;rewrite ^/?homesick.html$ /index.php?m=Blog&a=blogList&nav=2 last;rewrite ^/?homesick-([0-9]+).html$ /index.php?m=Blog&a=blogList&nav=2&p=$1 last;rewrite ^/?playground.html$ /index.php?m=Blog&a=blogList&nav=3 last;rewrite ^/?playground-([0-9]+).html$ /index.php?m=Blog&a=blogList&nav=3&p=$1 last;rewrite ^/?tag-([0-9]+).html$ /index.php?m=Blog&a=readByTags&tag=$1 last;}
return array( //一级路由 'blog/index'=>'./', 'blog/about'=>'about.html', 'blog/tags' =>'tags.html', //二级路由 'blog/blog' =>array( 1=>'[id].html', 2=>'[id]-[p].html' ), 'blog/readbytags'=>array( 1=>'tag-[tag].html', 2=>'tag-[tag]-[p].html' ), //三级路由 'blog/bloglist'=>array( 'nav'=>array( '1'=>array( 1=>'notebook.html', 2=>'notebook-[p].html', ), '2'=>array( 1=>'homesick.html', 2=>'homesick-[p].html', ), '3'=>array( 1=>'playground.html', 2=>'playground-[p].html', ), ) ));
Url函数以及路由函数
/** * 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){ //导入路由 static $router_ruler = array(); if(empty($router_ruler)){ $router_ruler = include(dirname(__FILE__).'/route.php'); } $real_url = route($router_ruler,$url,$params); }else{ $real_url = urlBuild($url,$params); } return $real_url;} /** * @param array $router_ruler 路由表 * @param string $url 路由键 * @param array $params 参数列表 */function route($router_ruler,$url,$params){ //路由规则里全写成小写吧 $router_key = strtolower(trim(trim($url),'/')); if(isset($router_ruler[$router_key])){ //一级路由 $real_url = $router_ruler[$router_key]; //由于规定参数格式必须是数组,所以这里只存在是数组和不是数组(为空)的情况 if(is_array($real_url)){ //看其是不是索引数组 if(array_product(array_map('is_numeric', array_keys($real_url)))==1){ //二级路由 if(is_array($params)){ $real_url = routeMatch($real_url[count($params)],$params); } }else{ //三级路由 foreach($params as $k =>$v){ if(array_key_exists($k,$real_url)){ $routeReg = $real_url[$k][$v][count($params)]; unset($params[$k]); $real_url = routeMatch($routeReg,$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('/',trim($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 $routeReg 路由规则字符串,类似于'tag'=>'tag_[tag].html' * @param string $params 需要替换正则字符串里面的关键字的实际参数值 * @return string $routeReg 返回最终匹配完的伪静态地址 */function routeMatch($routeReg,$params){ foreach($params as $key =>$value){ if(strstr($routeReg,'['.$key.']')){ $routeReg = str_replace('['.$key.']',$value,$routeReg); } } return $routeReg;}
在头部添加路由判断保证最终访问地址为伪静态地址
if(defined('ROUTE') && ROUTE){ if(strstr($_SERVER['REQUEST_URI'],'index.php')){ parse_str($_SERVER['QUERY_STRING'],$params); if(in_array($params['a'],array('blog','bloglist','readbytags'))){ switch(strtolower($params['a'])){ case 'blog': $route = $params['id']; break; case 'bloglist': $type = array(1=>'notebook',2=>'homesick',3=>'playground'); $route = $type[$params['nav']]; break; case 'readbytags': $route = 'tag-'.$params['tag']; break; } if($params['p']<2){ header('Location:'.SITE.'/'.$route.'.html'); }else{ header('Location:'.SITE.'/'.$route.'-'.$params['p'].'.html'); } } }}