简体   繁体   中英

Pretty URL via htaccess using any number of parameters

Actually i have this URL:

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

But i want to have this URL format:

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

So the "contact" goes to variable $_GET["site"] and rest of parameters should be able to access via $_GET["param1"] , $_GET["param2"] etc. The problem is, it has to work with any number of parameters (there could be param4 or even param50 or any other name of parameter). Is it possible via htaccess to cover all these cases?

Mod_rewrite has a maximum of 10 variables it can send:

RewriteRule backreferences : These are backreferences of the form $N (0 <= N <= 9), which provide access to the grouped parts (in parentheses) of the pattern, from the RewriteRule which is subject to the current set of RewriteCond conditions. mod_rewrite manual

so what you desire is NOT possible with htaccess only. a common way is to rewrite everything to one file and let that file determine what to do in a way like:

.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;
    }
}

Garytje's answer is almost correct.

Actually, you can achieve what you want with htaccess only , even if this is not something commonly used for that purpose.

Indeed, it would be more natural to delegate the logic to a script. But if you really want to do it with mod_rewrite , there are a lot of techniques to simulate the same behaviour. For instance, here is an example of workaround:

# 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]

From your initial example, /contact/param1:value1/param2:value2/param3:value3 will first be rewritten to /contact/param2:value2/param3:value3?param1=value1 . Then, mod_rewrite will match it again and rewrite it to /contact/param3:value3?param1=value1&param2=value2 . And so on, until no pair key:value is found after /contact/ . Finally, it is rewritten to /index.php?site=contact&param1=value1&param2=value2&param3=value3 .

This technique allows you to have a number of parameters greater than 9 without being limited by mod_rewrite . You can see it as a loop reading the url step by step. But, again, this is maybe not the best idea to use htaccess only for that purpose.

This is entirely doable using some creative htaccess and PHP. Effectively what you are doing here is telling Apache to direct all page requests to index.php if they are not for a real file or directory on the server...

## 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]

After this all you need to do is go into PHP and access the full user requested URL structure using the $_SERVER['REQUEST_URI'] superglobal and then break it down into an array using explode("/", $_SERVER['REQUEST_URI']) .

I currently use this on a number of my sites with all of the sites being served by index.php but with url structures such as...

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

which is then processed by the explode command to appear in an array as... 0=>"forums", 1=>"11824-some-topic-name",2=>"reply"

Try this..

.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;
  }

This is doable using only htaccess with something along the lines of...

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

([a-zA-Z0-9]+) will match alpha-numeric strings. :{1} will match 1 colon.

Expanding from there will probably be required based on weird URLs that turn up.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM