mod_rewrite:使用环境变量防止多次重写

时间:2012-08-04 02:52:58

标签: apache .htaccess mod-rewrite

我目前正在为* .php返回404错误,并在内部将所有请求重定向到PHP文件(如果存在),使用以下内容:

RewriteCond %{REQUEST_URI} /(?!index$)
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.+)$ /$1.php [QSA,L,E=norewrite:1]

RewriteCond %{ENV:norewrite} !1
RewriteCond %{REQUEST_URI} \.php$
RewriteRule ^(.+)$ - [R=404]

这很好用。但是,我希望能够从文件中提供PHP(或其他)源(具有适当的扩展名)。 index.php.src,如果直接访问index.php.src也返回404。

RewriteCond %{REQUEST_URI} /(?!index$)
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.+)$ /$1.php [QSA,L,E=norewrite:1]

RewriteCond %{ENV:norewrite} !1
RewriteCond %{REQUEST_FILENAME}\.src -f
RewriteRule ^(.+)$ /$1.src [L,E=norewrite:1]

RewriteCond %{ENV:norewrite} !1
RewriteCond %{REQUEST_URI} \.php$ [OR]
RewriteCond %{REQUEST_URI} \.src$
RewriteRule ^(.+)$ - [R=404]

这似乎不起作用。它在内部重定向到index.php,然后重定向到index.php.src,然后重定向到404s。

有趣的是,在第一个示例中,环境变量DOES阻止第二个规则集执行,并且页面按预期加载。当我添加您在第二个示例中看到的中间规则集时,环境变量似乎不再有任何影响。 如果我从第二个样本中删除第二个规则集,将其他行保留在最后一个规则集中,就像它第一个样本一样(除了请求例如index.php.src返回404,这就是我想要的)

由于各种原因,为此目的使用查询字符串是不可接受的,它必须是环境变量。

我该如何使这项工作?我做错了什么?

修改 如果我解释得很差(我很确定我做了)......

  • 存在以下两个文件:'index.php'和'index.php.src'
  • 如果我使用第一组规则请求http://domain.com/,我会收到我的主页(正如预期的那样)。使用第二组规则,我得到404.使用第二组规则,减去第二节,我得到我的主页(正如预期的那样)。
  • 如果我使用任一套规则请求http://domain.com/index,我会按预期获得404.
  • 如果我使用任一套规则请求http://domain.com/index.php,我会得到一个404.这是第一套预期的,但我希望能够提供'index.php的内容。 src”中。
  • 如果我使用第一组规则请求http://domain.com/index.php.src,我会得到'index.php.src'的内容,正如预期的那样,因为* .src上的规则为404不在那一组。无论有没有第二节,我都会按照预期获得404,无论是否有第二节。

问题似乎出现在第二节,但我无法弄清楚出了什么问题......

1 个答案:

答案 0 :(得分:0)

这就是我所做的工作:

RewriteCond %{IS_SUBREQ} false
RewriteCond %{REQUEST_URI} /(?!index$)
RewriteCond %{ENV:REDIRECT_STOP} !1
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.+)$ /$1.php [QSA,L,E=STOP:1]

RewriteCond %{IS_SUBREQ} false
RewriteCond %{ENV:REDIRECT_STOP} !1
RewriteCond %{REQUEST_FILENAME}\.src -f
RewriteRule ^(.+)$ /$1.src [L,E=STOP:1]

RewriteCond %{IS_SUBREQ} false
RewriteCond %{ENV:REDIRECT_STOP} !1
RewriteCond %{REQUEST_URI} \.php$ [OR]
RewriteCond %{REQUEST_URI} \.src$
RewriteRule ^(.+)$ - [R=404]

你会注意到我添加了%{IS_SUBREQ}位,这有助于导致它导致404的主页重定向问题。此时,查询字符串方法变得可以接受了,我确实让它使用了该方法,但我不是那种类型,我知道这可以做到,我会去做(我做了!)

除了将变量名称从'norewrite'更改为'STOP'之外,为了清楚起见,我了解到,当发生内部重定向时,mod_rewrite设置的环境变量以'REDIRECT_'为前缀。这就是为什么设置'norewrite'('STOP')的值,然后检查相同的变量,这是无效的。当我在检查行中将'REDIRECT_'附加到它时,它现在表现得如预期。

  • 请求'/ awesome'将处理'awesome.php'并返回其输出
  • 请求'/awesome.php'将返回'awesome.php.src'的内容(这是'awesome.php'的符号链接)
  • 请求'awesome.php.src'将返回404

这正是我想要的!希望这也可以帮助其他人。