TransWikia.com

Crafting a regex for mod_rewrite with more than nine parameters

Webmasters Asked by Mike -- No longer here on February 20, 2021

Say for example, I have a URL in this format:

http://example.com/(mobile-or-desktop-flag)/(major-venue-category)/(smaller-venue-category)/(venue-name)/(month)-(day)-(year)/(picture-number)/(user-action-on-picture)/(request-ajax-or-not)

where the text in parenthesis represent the parameter data.

and some example URLs are:

http://example.com/desktop/big/nightclubs/bloke/jan-1-2015/1/download/no-ajax
http://example.com/desktop/small/lounges/oko-blu/feb-2-2014/6/share/no-ajax
http://example.com/mobile/tiny/bars/honest-lawyer/mar-3-2013/9/report/ajax

With mod_rewrite, I know I can use $1 through $9 for the first nine parameters, but here, I have 10 parameters, and $10 is considered first parameter with a zero added to it. See RewriteCond at http://httpd.apache.org/docs/current/mod/mod_rewrite.html

I’m just wondering, is there any way one can include a variable 10th parameter in a rewrite rule, or will I have to merge two parameters into one and extract them into two via a server-side script?

2 Answers

You can also utilize te behavior of .htaccess, remembering that the generated url will be passed again and process the url in cycles, in the first you can deal with a group of parameters, and in the second with the other group...

You can see the flow in this diagram

The image is Taken from here

# This is a .htaccess file
# This will match the full pattern, that has to be adapted to any case, in this particular case will match "one/two/three/four/five/six/seven/eight/nine/ten/" ten parameters path
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(all_parameters_matched|processed_first_group)
RewriteRule ^((?:.+)/(?:.+)/(?:.+)/(?:.+)/(?:.+)/(?:.+)/(?:.+)/(?:.+)/(?:.+)/(?:.+)/?)$ all_parameters_matched/$1 [QSA,L]

# This deals with the first group of parameters
RewriteRule ^all_parameters_matched/([^/]+)/([^/]+)/([^/]+)/(.*)$ processed_first_group/$4?param1=$1&param2=$2&param3=$3 [QSA]

# This deals with the second group of parameters
RewriteRule ^processed_first_group/([^/]+)/([^/]+)/(.*)$ /script.php?param4=$1&param5=$2&the_rest=$3 [QSA]

In the example above it processes only five parameters in two parts, but you could get the idea.

Answered by Jesús on February 20, 2021

is there any way one can include a variable 10th parameter in a rewrite rule

As far as I'm aware you can only use the backreferences $0..$9 ($1 to $9 references the parenthesised/captured groups and $0 references the entire pattern that is matched) in Apache regex (eg. mod_rewrite, etc) to reference captured groups in the RewriteRule pattern (%0..%9 for the last matched CondPattern).

Workarounds:

  1. Like you suggest, you could merge two or more parameters into one and let your server-side script parse the URL. The date (month-day-year) is the obvious one. You could simply use mod_rewrite to validate the URL and let your server-side script parse the entire URL into its component parts (a front-controller).

  2. As an extension to the above. You could merge two or more params and rewrite the URL a second time, combining the params into the correct format required by the script you are rewriting to. For example, take the month-day-year parameter(s). If the script you were rewriting to required the date in universal date format (year-month-day) then you could first capture and convert this into one parameter (together with the remainder of the URL). For example:

    RewriteRule ^(w+/[w-]+/[w-]+/[w-]+)/([a-z]{3})-(d{1,2})-(d{4})/(.*) /$1/$4-$2-$3/$5
    RewriteRule ^(desktop|mobile)/([w-]+)/([w-]+)/([w-]+)/(d{4}-[a-z]{3}-d{1,2})/(d{1,3})/(download|share|report)/(no-ajax|ajax) /script.php?platform=$1&majorcat=$2&minorcat=$3&vname=$4&date=$5&picnum=$6&action=$7&ajax=$8 [L]
    
  3. Avoid capturing groups for any groups you don't need in the current rewrite. ie. Make it a non-capturing group by prefixing with ?:, for example: (?:desktop|mobile).

Answered by MrWhite on February 20, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP