嗨,老铁,欢迎来到我的博客!

如果觉得我的内容还不错的话,可以关注下我在 segmentfault.com 上的直播。我主要从事 PHP 和 Java 方面的开发,《深入 PHP 内核》作者之一。

[视频直播] PHP 进阶之路 - 亿级 pv 网站架构的技术细节与套路 直播中我将毫无保留的分享我这六年的全部工作经验和踩坑的故事,以及会穿插着一些面试中的 考点难点加分点

周梦康 发表于 2014-03-16 4523 次浏览 标签 : ZzBlog

最新代码请参考: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;
}

嗨,老铁,欢迎来到我的博客!

如果觉得我的内容还不错的话,可以关注下我在 segmentfault.com 上的直播。我主要从事 PHP 和 Java 方面的开发,《深入 PHP 内核》作者之一。

[视频直播] PHP 进阶之路 - 亿级 pv 网站架构的技术细节与套路 直播中我将毫无保留的分享我这六年的全部工作经验和踩坑的故事,以及会穿插着一些面试中的 考点难点加分点

评论列表