I have the following URL...
http://localhost/http.mygarble.com/foundationsofwebprogramming/86
...that I want to convert into the following:
http://localhost/http.mygarble.com/php/blog.php?subdomain=foundationsofwebprogramming&page=posts&label=86
I thought I could achieve this with the following rule:
RewriteRule ([^/]+)/([^/]+)$ php/blog.php?subdomain=$1&page=post&label=$2 [NC,L]
However what I find is that this rule is applied repeatedly, resulting in an internal server error. I understand that when the URI is transformed using this rule, the resulting URI will also match the rule, and therefore it is applied again ad-infinitum.
My previous (admittedly rather hazy) understanding was that the [L] flag would stop further processing, although I now understand that this simply means that only the remainder of the rules are skipped, and does not stop the rewrite engine running through the rules again.
I can fix this problem by adding the following condition...
RewriteCond $0 !php/blog.php
RewriteRule ([^/]+)/([^/]+)$ php/blog.php?subdomain=$1&page=post&label=$2 [NC,L]
...or by writing a more specific regular expression. But what I really want to do is find a way of stopping the rewrite engine from attempting ANY further matches once this rule is matched once. Is this possible?
Many thanks.
In your rewrite, the ^ signifies the start of the string, the (. *) says to match anything, and the $ signifies the end of the string. So, basically, it's saying grab everything from the start to the end of the string and assign that value to $1.
The RewriteCond directive defines a rule condition. One or more RewriteCond can precede a RewriteRule directive. The following rule is then only used if both the current state of the URI matches its pattern, and if these conditions are met.
mod_rewrite works through the rules one at a time, processing any rules that match the requested URL. If a rule rewrites the requested URL to a new URL, that new URL is then used from that point onward in the . htaccess file, and might be matched by another RewriteRule further down the file.
Usually 2 methods are used.
The first one is a Rewrite Condition testing that the requested file is not a real file. When internal recursion arise your php/blog.php is a real file and rewriterule is not executed the 2nd time. Side-effect is that any request for a file which exists won't be rewritten (which can be good side effect)
RewriteCond %{REQUEST_FILENAME} !-f
The second solution is to check you're not in an internal redirection with:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
Side effect of this 2nd solution is that the rewriteRule cannot be applied if some other rules are applied before (if you want some internal redirection to run after a first pass of rewriting in fact).
Edit
For completion I will add a third method: the [NS] or [nosubreq] tag seems to be doing the same thing. Preventing the rule usage after an internal redirection.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With