开发者

How can I get mod_rewrite to match a rule just once

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 aga开发者_如何学编程in.

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.


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.


And the third method is to upgrade apache to 2.3.9 or higher and use [END] flag instead of [L].

No side effects

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜