Mod_Rewrite规则冲突让我疯狂

时间:2012-03-24 08:46:51

标签: php apache .htaccess mod-rewrite

我有一个.htaccess如下,有些规则是冲突的 - 我需要以某种方式制定一个条件,以便它们不会

RewriteEngine On
RewriteRule ^search$ results_template.php [L]
RewriteRule ^load-([a-z0-9-]+)$ index.php?key=$1 [L]
RewriteRule ^([a-z0-9-]+)$ http://domain.com/share/index.php?key=$1 [L]

.htaccess文件位于http://domain.com/directory/.htaccess


第一条规则应该只是将名称search重写为results_template.php并停止处理更多规则

http://domain.com/directory/search

负载

http://domain.com/directory/results_template.php


第二条规则应该从<{p>}取abcdef-1

http://domain.com/directory/load-abcdef-1

并将其作为参数发送到

http://domain.com/directory/index.php?key=abcdef-1然后停止处理规则。


第三条规则应该从abcdef-1开始

http://domain.com/directory/abcdef-1

并将其作为参数发送到

http://domain.com/share/index.php?key=abcdef-1然后停止处理规则。


我遇到的问题是无论我如何在请求http://domain.com/directory/search时尝试将这些内容完美地放在一起,调用第三条规则并重定向。

我确信这只是完全的疲倦或完全愚蠢,但我现在已经在这个小小的步骤上进行了太多时间,所以任何帮助都会非常好。感谢

3 个答案:

答案 0 :(得分:1)

你需要RewriteConds:

RewriteEngine On
RewriteBase /directory
RewriteRule ^search$ results_template.php [L]
RewriteRule ^load-([a-z0-9-]+)$ index.php?key=$1 [L] 
RewriteCond %{QUERY_STRING} !^results_template.php
RewriteRule ^([a-z0-9-]+)$ http://domain.com/share/index.php?key=$1 [L]

E.g。用户请求/搜索,然后将查询转换为results_template.php。使用这个新查询/results_template.php再次检查所有规则,当然最后一条规则适合,因为它是最常用的规则。

答案 1 :(得分:1)

您需要将[NS]标志添加到第三个规则。这使得它不会触发内部子请求。

答案 2 :(得分:1)

@Jan解释说,当第一次重写ID search变为results_template.php时,你的问题就出现了。为了完全理解它,我将补充说,重写上的[L]标记实际上是停止重写并将生成的路径推送到Apache,但实际上在apache和mod-中执行内部重定向在内部重定向之后重新应用重写。

用mod-rewrite理解这是最困难的事情。使用RewriteLog和RewriteLogLevel可以帮助您在处理这些问题时非常简单地检测这些问题。

Jan提供的解决方案不起作用,但存在更通用的解决方案。如果您希望您的规则仅应用一次,仅在浏览器提供的网址上应用,如果您没有链接多个重定向层,那么确保规则的最简单方法是 阻止在内部重定向后应用。这可以通过在每个规则之前检查环境变量REDIRECT_STATUS为空来完成

# prevent this rule from being applied after first pass
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ...

修改

但我刚刚阅读@baynezy(+1)的答案,而[NS]或[nosubreq]标签似乎在做同样的事情。你也应该尝试一下。