Rewriting an arbitrary number of path segments to query parameters

First of all: You shouldn’t use .* if you can be more specific, like in this case [^/]+. Because multiple .* can cause immense backtracking. So:

RewriteRule ^viewshoplatest/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ /viewshoplatest.php?$1=$2&$3=$4&$5=$6&$7=$8&$9=$10&$11=$12&$13=$14&$15=$16

You can use a took like RegexBuddy to see the difference in how these regular expressions are processed.

But since mod_rewrite does only allow to reference the first nine groups (see Tim’s answer), you could use an iterative approach and process one parameter at a time:

RewriteRule ^viewshoplatest/([^/]+)/([^/]+)/([^/]+/[^/]+/.*)$ /viewshoplatest/$3?$1=$2 [QSA,N]
RewriteRule ^viewshoplatest/([^/]+)/([^/]+)/([^/]*)/?$ /viewshoplatest.php?$1=$2&$3 [QSA,L]

The first rule will process one parameter pair at a time (except the last pair) by append it to the already existing ones (see QSA flag) and then restart the rewriting process without incrementing the internal recursion counter (see N flag). The second rule will then rewrite the last parameter pair (or just the name) and end the iteration.

But since using the N flag might be dangerous as it can cause an infinite recursion, you could also use PHP to parse the requested path:

$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$segments = implode("https://stackoverflow.com/", trim($_SERVER['REQUEST_URI_PATH'], "https://stackoverflow.com/"));
array_shift($segments); // remove path prefix "/viewshoplatest"
for ($i=0, $n=count($segments); $i<$n; ) {
    $_GET[rawurldecode($segments[$i++])] = ($i < $n) ? rawurldecode($segments[$i++]) : null;
}

Now you just need this rule to pass the request through:

RewriteRule ^viewshoplatest(/|$) /viewshoplatest.php [L]

Leave a Comment