I would like to do a .htaccess
redirect, depending on the number of path segments in the URL. However, if this condition is detected then no more RewriteRule
conditions should be evaluated.
Let's suppose I have URL like this:
http://www.example.com/level1/level2/level3/...../levelx
and I would like to do a redirection using RewriteRule
, depending on the number of "levels" that I have on the URL.
For instance, if I have three of more "levels" (something like http://www.example.com/levels/level1/level2/level3/level4/../100
). I would like to redirect to something like: http://www.example.com/whatever.php?id=100
page
However I would use something like:
RewriteRule ^levels/(.+)/(.+)/(.+)/(.+)/(.+) basedir/whatever.php?id=$5
But the key on this question is to create a condition that acts when a number of detected slashes on original URL is more than on number (that could be variable).
There is no way of conventional "counting" in .htaccess
. (You can define server-side rewrite maps that link to external programs, but I assume that is out of scope for this question.)
If you have a limited number of path segments then you can hardcode the responses. For example:
RewriteRule ^levels/$ /whatever.php?query=0 [R,L]
RewriteRule ^levels/[^/]*$ /whatever.php?query=1 [R,L]
RewriteRule ^levels/[^/]*/[^/]*$ /whatever.php?query=2 [R,L]
RewriteRule ^levels/[^/]*/[^/]*/[^/]*$ /whatever.php?query=3 [R,L]
RewriteRule ^levels/[^/]*/[^/]*/[^/]*/[^/]*$ /whatever.php?query=4 [R,L]
RewriteRule ^levels/[^/]*/[^/]*/[^/]*/[^/]*/[^/]*$ /whatever.php?query=5 [R,L]
I would use something like:
RewriteRule ^levels/(.+)/(.+)/(.+)/(.+)/(.+) basedir/whatever.php?id=$5
Capturing backreferences doesn't "count" them. $5
simply holds the value of the 5th captured subpattern. This is equivalent of hardcoding. However, bear in mind that the pattern .+
will also capture slashes (ie. URL path segments). So, the above regex only "counts" the first 5, when there could be many more. There is also a technical limit of 9 backreferences.
A possible workaround is to build a query string (appending 1 character at a time) for each slash (path segment) found in the source string.
For example:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^1*$
RewriteRule ^levels/(.*)/(.*)$ levels/$1-$2?%{QUERY_STRING}1 [N,DPI]
RewriteRule ^levels/([^/]*)$ /whatever.php?query=%{QUERY_STRING} [R,L]
Given a request for:
http://www.example.com/levels/lev1/lev2/lev3/lev4/lev5/lev6/lev7/lev8/lev9/lev10
Would result in an external redirect to:
http://www.example.com/whatever.php?query=111111111
Then in whatever.php
you would count the length of the query
URL parameter to determine the number of levels. Since we are strictly counting the number of slashes, the number of "levels" is count+1.
The first RewriteRule
repeatedly replaces all slashes in the original URL-path with hyphens (just an arbitrary character) via a looping internal rewrite (N
flag). On each iteration, when a slash is replaced, we append a 1
to the end of the query string. The DPI
flag (D
iscard P
athname I
nformation) is required in this example to discard additional path-info from the original request that would otherwise be appended to the rewritten URL - this is necessary in order to prevent an endless rewrite loop (and possible server crash!).
The second RewriteRule
triggers the external redirect, once all the additional slashes have been replaced in the URL-path. The query string (that now consists of a string of the form "11111") is appended to the redirected URL as part of the query
URL parameter.
1
. This could perhaps be adapted as required.Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments