htaccess重写同一级别的不同get参数

时间:2016-06-06 12:16:00

标签: php .htaccess mod-rewrite

首先,我问这个问题on stack让网址重写工作。我将其扩展为包含第3个参数,但是当第3个参数不同时我失败了。

我已经创建了一个列表,其中列出了我目前拥有的GET参数以及我想将其转化为的内容:

~/tournament/profile/username           /tournament/index.php?view=profile&id=username
~/tournament/profile/username/edit      /tournament/index.php?view=profile&id=username&action=edit
~/tournament/profile/username/overview  /tournament/index.php?view=profile&id=username&page=overview
~/tournament/profile/username/teams     /tournament/index.php?view=profile&id=username&page=teams


~/tournament/teams/create               /tournament/index.php?view=teams&action=create
~/tournament/teams/teamname             /tournament/index.php?view=teams&id=teamname
~/tournament/teams/teamname/edit        /tournament/index.php?view=teams&id=teamname&action=edit
~/tournament/teams/teamname/delete      /tournament/index.php?view=teams&id=teamname&action=delete
~/tournament/teams/teamname/members     /tournament/index.php?view=teams&id=teamname&page=members

~/tournament/cups                       /tournament/index.php?view=cups
~/tournament/cups/id                    /tournament/index.php?view=cups&id=cupid
~/tournament/cups/id/rules              /tournament/index.php?view=cups&page=rules
~/tournament/cups/id/matches            /tournament/index.php?view=cups&page=matches
~/tournament/cups/id/brackets           /tournament/index.php?view=cups&page=brackets
~/tournament/cups/id/teams              /tournament/index.php?view=cups&page=teams

~/tournament/passwords/forgot_password  /tournament/index.php?view=password&action=forgot_password
~/tournament/passwords/reset            /tournament/index.php?view=password&action=reset

~/tournament/admin                      /tournament/admin.php
~/tournament/admin/users                /tournament/admin.php?view=users
~/tournament/admin/users/username       /tournament/admin.php?view=users&id=username

使用以下.htaccess:

RewriteEngine On
RewriteBase /tournament/

# Skip if existing file/folder
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]

RewriteCond %{THE_REQUEST} \s/tournament/index\.php\?view=([^&\s]+)\s [NC]
RewriteRule ^ %1? [R=301,L]
RewriteCond %{THE_REQUEST} \s/tournament/index\.php\?view=([^&\s]+)&id=([^&\s]+)\s [NC]
RewriteRule ^ %1/%2? [R=301,L]
RewriteCond %{THE_REQUEST} \s/tournament/index\.php\?view=([^&\s]+)&id=([^&\s]+)&action=([^&\s]+)\s [NC]
RewriteRule ^ %1/%2/$3? [R=301,L]
RewriteCond %{THE_REQUEST} \s/tournament/index\.php\?view=([^&\s]+)&id=([^&\s]+)&page=([^&\s]+)\s [NC]
RewriteRule ^ %1/%2/$3? [R=301,L]


RewriteRule ^([^/]+)$ index.php?view=$1 [L]
RewriteRule ^([^/]+)/([^/]+)$ index.php?view=$1&id=$2 [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)$ index.php?view=$1&id=$2&action=$3 [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)$ index.php?view=$1&id=$2&page=$3 [L]

主要关注有关/profile/username/edit/profile/username/overview的网址。

我添加了以下规则:

RewriteCond %{THE_REQUEST} \s/tournament/index\.php\?view=([^&\s]+)&id=([^&\s]+)&page=([^&\s]+)\s [NC]
RewriteRule ^ %1/%2/$3? [R=301,L]

RewriteRule ^([^/]+)/([^/]+)/([^/]+)$ index.php?view=$1&id=$2&page=$3 [L]

要处理&page参数,但是当我的网址重写为/profile/username/team/overview时,我会返回编辑页面,而不是概述页面。

处理交换变量的最有效方法是什么?即

?view=*&id=*&action=* vs ?view=*&id=*&page=*

再次感谢。

2 个答案:

答案 0 :(得分:0)

您可以使用单一入口点技术。

RewriteEngine On
RewriteBase /tournament/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L,QSA]

现在您需要解析index.php中请求的URL以获取参数。这样的事情:

$view = 'default';
$id = '0';
$params = array();

if ($_SERVER['REQUEST_URI'] != '/') {
    try {
        $url_path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
        $uri_parts = explode('/', trim($url_path, ' /'));

        if (count($uri_parts) % 2) {
            throw new Exception();
        }

        $view = array_shift($uri_parts); 
        $id = array_shift($uri_parts);

        // /key1/value1/key2/value2 -> array()
        for ($i=0; $i < count($uri_parts); $i++) {
            $params[$uri_parts[$i]] = $uri_parts[++$i];
        }
    } catch (Exception $e) {
        $module = '404';
        $action = 'main';
    }
}

答案 1 :(得分:0)

您可以使用:

RewriteEngine on
#redirect from "/tournament/index.php?view=foo&id=bar&action=edit" to "/tournament/foo/bar/edit"
RewriteCond %{THE_REQUEST} /tournament/index.php\?view=([^&]+)&id=([^&]+)&action=(edit)\sHTTP [NC]
RewriteRule ^ /tournament/%1/%2/%3? [L,R]
#redirect from "/tournament/index.php?view=foo&id=bar" to "/tournament/foo/bar/"
RewriteCond %{THE_REQUEST} /tournament/index.php\?view=([^&]+)&id=([^&]+)\sHT [NC]
RewriteRule ^ /tournament/%1/%2? [L,R]
#redirect from "/tournament/index.php?view=foo" to "/tournament/foo"
RewriteCond %{THE_REQUEST} /tournament/index.php\?view=([^&]+)\sHTTP [NC]
RewriteRule ^ /tournament/%1? [L,R]
#internally rewrite external requests to orignal location
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^([^/]+)/?([^/]*)/?(.*?)/?$ /tournament/index.php?view=$1&id=$2&page=$3 [NC,L]