TP正则路由在U方法中不生效

浏览:1525 发布日期:2013/12/19 分类:求助交流 关键字: 正则路由 U方法
最近在做项目的时候想定义一下伪静态规则,就想到了TP的路由功能。
然而我在配置文件中设置之后却怎么都不成功'URL_MODEL' => 2,
'URL_HTML_SUFFIX' => 'html',
'URL_PATHINFO_DEPR' => '/',
'URL_ROUTER_ON' => true,
'URL_ROUTE_RULES' =>array (
     '/^blog\/(\d+)$/'        => 'Home/Blog/index?id=:1',
),
项目采用了分组模式。
本以为配置完之后效果应该是:http://domain.com/blog/1
结果确是:http://domain.com/Home/Blog/1.html

最后去看了下U方法的源码,发现当里面至判断了url_model等于0和else的情况。
但是在else中没有调用URL_ROUTE_RULES进行url匹配。那我设置的正则还有什么用?

百度之后看到有人这么解决的

修改ThinkPHP/Common/functions.php 246行。
// URL组装
$depr = C('URL_PATHINFO_DEPR');
if($url) {
....
}从这里开始修改$flag=true;
    if(C('URL_MODEL') == 0) { // 普通模式URL转换
        $ap = pathinfo(__APP__);
        if ($ap['extension'] != 'php') { //临时解决
           $url        =   __APP__ .'/?'.http_build_query(array_reverse($var));
        } else {
           $url        =   __APP__ .'?'.http_build_query(array_reverse($var));
        }
        
        if(!empty($vars)) {
            $vars   =   urldecode(http_build_query($vars));
            $url   .=   '&'.$vars;
        }
        $flag=false;
    }

    if(C('URL_MODEL') == 2){
        $routes = C('URL_ROUTE_RULES');
        if (false === strpos('/', $url)) {
            $url    =   implode($depr,array_reverse($var));
        }
        $_url=array_merge(parseUrl($url), $vars);
        foreach ($routes as $rule=>$r_route){
            $r_route = str_replace('/', $depr, $r_route);
            $_route=parseUrl(str_replace(':', '~',$r_route));
            if(url_compare($_url, $_route))break;
        }
        if(url_compare($_url, $_route)){
            foreach ($_route as $key=>$val){
                if($key=='m'||$key=='a')continue;
                if( preg_match("/~/",$val) ){
                    $rule=preg_replace("/(\(\\\[\w]\+\))/",$_url[$key],$rule,1);
                }
            }
            //去掉最后的"/"
            $url = __APP__.'/'.ltrim(rtrim(trim($rule,'/'), '$'), '^');
            $url = str_replace('\\', '', $url);
            $flag = false;
        }
    }
    if($flag){ // PATHINFO模式或者兼容URL模式
        if(isset($route)) {
            $url    =   __APP__.'/'.rtrim($url,$depr);
        }else{
            $url    =   __APP__.'/'.implode($depr,array_reverse($var));
        }
        if(!empty($vars)) { // 添加参数
            foreach ($vars as $var => $val)
                $url .= $depr.$var . $depr . $val;
        }
        if($suffix) {
            $suffix   =  $suffix===true?C('URL_HTML_SUFFIX'):$suffix;
            if($pos = strpos($suffix, '|')){
                $suffix = substr($suffix, 0, $pos);
            }
            if($suffix && $url[1]){
                $url  .=  '.'.ltrim($suffix,'.');
            }
        }
    }
    if($domain) {
        $url   =  (is_ssl()?'https://':'http://').$domain.$url;
    }
    if($redirect) // 直接跳转URL
        redirect($url);
    else
        return $url;
下面是新增的2个方法function url_compare($url, $route){
    ksort($url);
    $url_keys=array_keys($url);
    ksort($route);
    $route_keys=array_keys($route);
    if ($url_keys!=$route_keys) {
        return false;
    }
    $flag = true;
    foreach ($route as $_key=>$_val) {
        if (false === strpos($_val, '~')) {
            if ($url[$_key] != $_val) {
                $flag = false;
                break;
            }
        }
    }
    return $flag;
}

function parseUrl($url) {
    $depr = C('URL_PATHINFO_DEPR');
    $var  =  array();
    if(false !== strpos($url,'?')) { // [分组/模块/操作?]参数1=值1&参数2=值2...
        $info   =  parse_url($url);
        $path = explode($depr, $info['path']);
        parse_str($info['query'],$var);
    }elseif(strpos($url, $depr)){ // [分组/模块/操作]
        $path = explode($depr, $url);
    }else{ // 参数1=值1&参数2=值2...
        parse_str($url, $var);
    }
    if(isset($path)) {
        $var[C('VAR_ACTION')] = array_pop($path);
        if(!empty($path)) {
            $var[C('VAR_MODULE')] = array_pop($path);
        }
        if(!empty($path)) {
            $var[C('VAR_GROUP')]  = array_pop($path);
        }
    }
    return $var;
}
想问下大家,还有什么方法可以实现?
最佳答案
评论() 相关
后面还有条评论,点击查看>>