fygesser fygesser - 1 year ago 68
Apache Configuration Question

Multiple RewriteRules for a single URL

I want to use multiple

to modify a single URL, but only the last rule gets applied.

Example INPUT (link loaded by a browser):



RewriteRule ^(.*)foo/(.*)$ $1nofoo/$2
RewriteRule ^(.*)bar(.*)$ $1nobar$2

EXPECTED OUTPUT (what Apache should actually look at):




As you can see, only the last rule was applied. Is there any way to make it work the way I want? All suggestions are welcome.

PS. I want to avoid creating a static, ugly rule like

^(.*)foo/bar(.*) $1nofoo/nobar$2

I need all the modifications to work independently of each other.


So here is exactly what I am trying to achieve. I have some links to a backend server:


Where $userid and $carid are some unique 12-char-long strings.

And I want to transform them to these:


And I want to achieve it using the least RewriteRules possible (I am looking for a dynamic solution).


I love the SO community! Your patience and willingness to help is truly amazing :)

So the very reason why I am interested in modifying the URL using multiple RewriteRules is because I expect that my backend might soon need to implement hundreds (if not thousands) of user-friendly URLs, and mapping all of them individually would be a waste of time and money. Therefore, I want to take advantage of the fact that all the user-friendly URLs consist of repetitive chunks that can be easily translated. The calls below represent the general three types of the user-friendly URLs I need to manage. The only difference within each type is $userid, $carid, and XXXX_of_a_thousand_functions.


All of these calls (and remember, there will be hundreds, or even thousands of them) need to be translated into these:


Seeing that there is a simple pattern governing the translation (I hope it is also visible to you), I thought I could create some simple rules for translating different 'chunks' of the user-friendly URL into the internal URL. For example:

RewriteRule ^(.*)user/([A-Za-z0-9]+)/(.*)$ $1$3&USER_ID=$2

Would be responsible for translating the piece

And because some calls have more than one 'chunk' to process, I need to be able to use multiple RewriteRules on a single URL, which I hope somewhat correlates with the title of the question :)

Answer Source

After UPDATE#1... to internally rewrite from the stated friendly URLs using mod_rewrite. Try the following directives in the root .htaccess file:

RewriteEngine On

# http://myserver.com/api/user/$userid/car/$carid/getSpeedRecordDetails
RewriteRule ^api/user/(\w{12})/car/(\w{12})/(getSpeedRecordDetails)$ /api/$3.php?userid=$1&carid=$2 [L]

# http://myserver.com/api/user/$userid/getUserDetails
RewriteRule ^api/user/(\w{12})/(getUserDetails)$ /api/$2.php?userid=$1 [L]

# http://myserver.com/api/car/$carid/getCarDetails
RewriteRule ^api/car/(\w{12})/(getCarDetails)$ /api/$2.php?carid=$1 [L]

\w{12} matches a 12 char long string of letters (upper/lower), numbers and underscore. However, this should be made as restrictive as possible. eg. if a valid id is only numeric then \d{12} would be preferable.

UPDATE#2 The process is almost the same as above....

RewriteBase /backend-api

# http://myserver.com/backend-api/user/$userid/car/$carid/<any>.do
RewriteRule ^backend-api/user/(\w{12})/car/(\w{12})/(\w+)\.do$ $3.php?USER_ID=$1&CAR_ID=$2 [L]

# http://myserver.com/backend-api/user/$userid/<any>.do
RewriteRule ^backend-api/user/(\w{12})/(\w+)\.do$ $2.php?USER_ID=$1 [L]

# http://myserver.com/backend-api/car/$carid/<any>.do
RewriteRule ^backend-api/car/(\w{12})/(\w+)\.do$ $2.php?CAR_ID=$1 [L]

Note the use of RewriteBase. This allows the URL-path to be removed from the RewriteRule substitution.

If /backend-api exists as a physical directory then these rules could instead go in /backend-api/.htaccess. Then you could remove the RewriteBase directive and modify the RewriteRule pattern by removing the backend-api/ portion from near the start of the pattern.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download