如何让mod_rewrite只匹配一次规则

Jam*_*ith 7 apache mod-rewrite

我有以下网址...

HTTP://localhost/http.mygarble.com/foundationsofwebprogramming/86

...我想转换成以下内容:

HTTP://localhost/http.mygarble.com/php/blog.php子域= foundationsofwebprogramming&页=岗位&标签= 86

我以为我可以通过以下规则实现这一目标:

RewriteRule ([^/]+)/([^/]+)$ php/blog.php?subdomain=$1&page=post&label=$2 [NC,L]
Run Code Online (Sandbox Code Playgroud)

但是,我发现重复应用此规则,导致内部服务器错误.我理解,当使用此规则转换URI时,生成的URI也将匹配规则,因此它将再次无限应用.

我之前(不可否认的是相当朦胧)的理解是[L]标志会停止进一步处理,虽然我现在明白这只是意味着只跳过规则的其余部分,并且不会阻止重写引擎再次运行规则.

我可以通过添加以下条件来解决此问题...

RewriteCond $0 !php/blog.php
RewriteRule ([^/]+)/([^/]+)$ php/blog.php?subdomain=$1&page=post&label=$2 [NC,L]
Run Code Online (Sandbox Code Playgroud)

...或者通过编写更具体的正则表达式.但我真正想做的是找到一种方法来阻止重写引擎在匹配一次此规则后尝试任何进一步的匹配.这可能吗?

非常感谢.

reg*_*ero 17

通常使用2种方法.

第一个是重写条件测试,请求的文件不是真实文件.当内部递归出现时,你的php/blog.php是一个真正的文件,并且第二次没有执行rewriterule.副作用是对任何存在的文件的请求都不会被重写(这可能是好的副作用)

RewriteCond %{REQUEST_FILENAME} !-f
Run Code Online (Sandbox Code Playgroud)

第二个解决方案是检查您是否在内部重定向中:

RewriteCond %{ENV:REDIRECT_STATUS} ^$
Run Code Online (Sandbox Code Playgroud)

第二个解决方案的副作用是,如果之前应用了其他一些规则,则无法应用rewriteRule(如果您希望在第一次重写之后运行一些内部重定向).

编辑

为了完成,我将添加第三种方法:[NS]或[nosubreq]标签似乎在做同样的事情.在内部重定向后阻止规则使用.

  • 似乎`[NS]`不适用于`RewriteRule`重写.第二种解决方案很好.谢谢! (3认同)

And*_*rew 5

第三种方法是将apache升级到2.3.9或更高版本并使用[END]标志而不是[L]。

无副作用