Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 739
Manny Avatar asked Mar 19 '16 14:03

Manny


2 Answers

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;
    }
}
like image 174
Garytje Avatar answered Oct 18 '22 14:10

Garytje


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.

like image 37
Justin Iurman Avatar answered Oct 18 '22 13:10

Justin Iurman