简体   繁体   English

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

[英]mod_rewrite: Prevent multiple rewrites using an environment variable

I'm currently returning a 404 error for *.php and internally redirecting all requests to a PHP file if one exists, using the following: 我目前正在为* .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]

This works fine. 这很好。 However, I wish to have the ability to serve up PHP (or other) source (with the appropriate extension), from files eg index.php.src, while having index.php.src also return a 404 if accessed directly. 但是,我希望能够从index.php.src之类的文件提供PHP(或其他)源(具有适当的扩展名),同时让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]

This does not appear to work. 这似乎不起作用。 It internally redirects to index.php, then to index.php.src, then 404s. 它在内部重定向到index.php,然后重定向到index.php.src,然后是404s。

What's interesting is that, in the first sample, the environment variable DOES prevent the second ruleset from executing, and the page loads as expected. 有趣的是,在第一个示例中,环境变量DOES阻止了第二个规则集的执行,并且页面按预期加载。 When I add that middle ruleset you see in the second sample, the environment variable no longer seems to have any effect. 当我添加第二个示例中的中间规则集时,环境变量似乎不再起作用。 If I remove that second ruleset from the second sample, leaving the additional lines in the last ruleset, as is, it behaves just like the first sample (except that requesting eg index.php.src returns a 404, which is what I want). 如果我从第二个示例中删除了第二个规则集,而将其他行保留在最后一个规则集中,则它的行为就与第一个示例一样(除非请求例如index.php.src返回404,这就是我想要的) 。

For various reasons, it would be unacceptable to use a query string for this purpose, it must be an environment variable. 由于各种原因,为此目的而使用查询字符串是不可接受的,它必须是环境变量。

How can I make this work? 我该如何进行这项工作? What am I doing wrong? 我究竟做错了什么?

Edit: In case I explained it poorly (I'm fairly sure I did)... 编辑:以防我解释得不好(我很确定我做到了)...

  • The following two files exist: 'index.php' and 'index.php.src' 存在以下两个文件:'index.php'和'index.php.src'
  • If I request http ://domain.com/ with the first set of rules, I get my homepage (as expected). 如果我请求带有第一组规则的http://domain.com/,则会得到我的主页(如预期)。 With the second set of rules, I get a 404. With the second set of rules, minus the second stanza, I get my homepage (as expected). 使用第二组规则,我得到404。使用第二组规则,减去第二节,我得到了我的主页(与预期的一样)。
  • If I request http ://domain.com/index with either set of rules, I get a 404, as expected. 如果我要求使用任何一组规则的http://domain.com/index,我都会得到一个404,正如预期的那样。
  • If I request http ://domain.com/index.php with either set of rules, I get a 404. This is expected with the first set, but I expect to be served the contents of 'index.php.src'. 如果我使用任何一组规则请求http://domain.com/index.php,我都会得到404。这在第一组规则中是预期的,但我希望将其提供给“ index.php.src”的内容。
  • If I request http ://domain.com/index.php.src with the first set of rules, I get the contents of 'index.php.src', as expected since the rule to 404 on *.src isn't in that set. 如果我请求使用第一组规则的http://domain.com/index.php.src,则会得到'index.php.src'的内容,这是预期的,因为* .src上的404规则不是在那个集合中。 I get a 404 as expected with the second set, with or without the second stanza. 无论有没有第二节,在第二组中我都能得到预期的404。

The problem appears to be in the second stanza, but I can't make out what's wrong... 问题似乎出在第二节,但我无法弄清楚出了什么问题...

Here's what I did that worked: 这是我所做的工作:

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]

You'll notice I added the %{IS_SUBREQ} bits, which helped with the homepage redirerect issue that was causing it to 404. At that point, the query string method became acceptable, and I did get it working with that method, but I'm not the type to jsut let it be at that, I knew this could be done and I was gonna do it (I did!) 您会注意到我添加了%{IS_SUBREQ}位,这有助于解决导致它返回404的首页重新分配问题。那时,查询字符串方法变得可以接受,并且确实可以使用该方法,但是'不是那种jsut的类型,我知道这是可以做到的,而我会做的(我做到了!)

Aside from changing the variable name from 'norewrite' to 'STOP', which I did for clarity, I learned that environment variables set by mod_rewrite are prefixed with 'REDIRECT_' when an internal redirect occurs. 除了将变量名从'norewrite'更改为'STOP'(为清楚起见)外,我还了解到在发生内部重定向时,由mod_rewrite设置的环境变量以'REDIRECT_'为前缀。 That's why setting the value of 'norewrite' ('STOP'), then checking that same variable, was not working. 这就是为什么设置'norewrite'('STOP')的值,然后检查相同的变量不起作用的原因。 When I appended 'REDIRECT_' to it in the check lines, it now behaves as expected. 当我在检查行中将“ REDIRECT_”附加到它之后,它现在的行为与预期的一样。

  • Requesting '/awesome' will process 'awesome.php' and return its output 请求'/ awesome'将处理'awesome.php'并返回其输出
  • Requesting '/awesome.php' will return the content of 'awesome.php.src' (which is a symlink to 'awesome.php') 请求“ /awesome.php”将返回“ awesome.php.src”的内容(这是“ awesome.php”的符号链接)
  • Requesting 'awesome.php.src' will return a 404 请求'awesome.php.src'将返回404

This is exactly what I wanted! 这正是我想要的! Hopefully this will help someone else, as well. 希望这也会对其他人有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM