使用任意数量的参数通过htaccess提供漂亮的URL

时间:2016-03-19 14:56:20

标签: php .htaccess mod-rewrite

其实我有这个网址:

http://www.example.com/index.php?site=contact&param1=value1&param2=value2&param3=value3

但我想要这种网址格式:

http://www.example.com/contact/param1:value1/param2:value2/param3:value3

因此,“联系人”转到变量$_GET["site"],其他参数应该能够通过$_GET["param1"]$_GET["param2"]等进行访问。问题是,它必须与任何数字一起使用参数(可能有param4甚至param50或任何其他参数名称)。是否可以通过htaccess来涵盖所有这些案件?

5 个答案:

答案 0 :(得分:7)

Mod_rewrite最多可以发送10个变量:

RewriteRule反向引用: 这些是$ N(0 <= N&lt; = 9)形式的反向引用,其提供对RewriteRule的模式的分组部分(括号中)的访问,RewriteRule受当前RewriteCond条件集的约束。 mod_rewrite manual

所以你想要的只是htaccess是不可能的。一种常见的方法是将所有内容重写为一个文件,并让该文件以如下方式确定要执行的操作:

的.htaccess

RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L,NC]

的index.php

$aUrlArray = explode('/',str_ireplace(',','/',$_SERVER['REQUEST_URI'])); // explode every part of url
foreach($aUrlArray as $sUrlPart){
    $aUrlPart = explode(':',$sUrlPart); //explode on :
    if (count($aUrlPart) == 2){ //if not 2 records, then it's not param:value
        echo '<br/>paramname:' .$aUrlPart[0];
        echo '<br/>paramvalue' .$aUrlPArt[1];
    } else {
        echo '<br/>'.$sUrlPart;
    }
}

答案 1 :(得分:4)

Garytje的回答几乎是正确的。

实际上,可以使用htaccess 实现您想要的效果,即使这不是通常用于此目的的内容。

实际上,将逻辑委托给脚本会更自然。但是如果你真的想用 mod_rewrite 来做,那么有很多技术可以模拟相同的行为。例如,以下是解决方法的示例:

# Extract a pair "key:value" and append it to the query string
RewriteRule ^contact/([^:]+):([^/]+)/?(.*)$ /contact/$3?$1=$2 [L,QSA]

# We're done: rewrite to index.php
RewriteCond %{QUERY_STRING} !^$
RewriteRule ^contact/$ /index.php?site=contact [L,QSA]

从最初的示例开始,/contact/param1:value1/param2:value2/param3:value3将首先重写为/contact/param2:value2/param3:value3?param1=value1。然后, mod_rewrite 将再次匹配并将其重写为/contact/param3:value3?param1=value1&param2=value2。依此类推,直到在key:value之后找不到对/contact/。最后,它被重写为/index.php?site=contact&param1=value1&param2=value2&param3=value3

此技术允许您拥有大于9的多个参数,而不受 mod_rewrite 的限制。您可以将其视为循环读取URL的循环。但是,再次,这可能不是为此目的仅使用htaccess 的最佳方法。

答案 2 :(得分:1)

使用一些有创意的htaccess和PHP完全可行。实际上你在这里做的是告诉Apache将所有页面请求指向index.php,如果它们不是服务器上的真实文件或目录......

## No directory listings
IndexIgnore *

## Can be commented out if causes errors, see notes above.
Options +FollowSymlinks
Options -Indexes

## Mod_rewrite in use.

RewriteEngine On

RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

RewriteCond %{REQUEST_URI} !^/index\.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]

在此之后,您需要做的就是进入PHP并使用$_SERVER['REQUEST_URI']超全局访问完整的用户请求的URL结构,然后使用explode("/", $_SERVER['REQUEST_URI'])将其分解为数组。

我目前在我的许多网站上都使用此功能,所有网站都由index.php提供,但网址结构如...

http://www.domain.com/forums/11824-some-topic-name/reply

然后由explode命令处理,以显示在数组中... 0=>"forums", 1=>"11824-some-topic-name",2=>"reply"

答案 3 :(得分:-1)

试试这个..

.htaccesss

  RewriteEngine on
    RewriteBase /

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule .* /index.php [L,QSA]

的index.php

  $uri = $_SERVER['REQUEST_URI'];
  $uri_array = explode( "/", $uri );

  switch ( $uri_array[0] ) {
    case '':
      /* serve index page */
    break;
    case 'contact':
       // Code
    break;
  }

答案 4 :(得分:-3)

只使用htaccess就可以实现......

([a-zA-Z0-9]+):{1}([a-zA-Z0-9]+)

([a-zA-Z0-9] +)将匹配字母数字字符串。 :{1}将匹配1个冒号。

可能需要根据出现的奇怪网址进行扩展。