Mod rewrite mod#u rewrite:why can';是否使用环境变量来防止递归?

Mod rewrite mod#u rewrite:why can';是否使用环境变量来防止递归?,mod-rewrite,apache2,Mod Rewrite,Apache2,为什么我不能使用类似的mod_rewrite规则: RewriteEngine On RewriteCond %{ENV:did_rewrite} !=true RewriteCond %{REQUEST_URI} ^(.*)/ RewriteRule (.*) %1/foo.php?original=$1 [E=did_rewrite:true] 看起来,在“递归”调用中,环境变量不知何故变得未设置……但我不明白为什么会发生这种情况 说得很清楚:我知道有很多方法可以防止这种递归。我想了解为什么

为什么我不能使用类似的
mod_rewrite
规则:

RewriteEngine On RewriteCond %{ENV:did_rewrite} !=true RewriteCond %{REQUEST_URI} ^(.*)/ RewriteRule (.*) %1/foo.php?original=$1 [E=did_rewrite:true] 看起来,在“递归”调用中,环境变量不知何故变得未设置……但我不明白为什么会发生这种情况

说得很清楚:我知道有很多方法可以防止这种递归。我想了解为什么这种特殊的方法不起作用。

我想你可能会有答案。总之,当Apache执行内部重定向时,它:

static apr\u table\u t*rename\u original\u env(apr\u pool\u t*p,apr\u table\u t*t)
{
常量apr\u数组\u头\u t*env\u arr=apr\u表\u elts(t);
const apr\u table\u entry\u t*elts=(const apr\u table\u entry\u t*)env\u arr->elts;
apr_table_t*new=apr_table_make(p、env_arr->nalloc);
int i;
对于(i=0;inelts;++i){
如果(!elts[i].key)
继续;
apr_table_setn(新的,apr_pstrcat(p,“重定向”),elts[i]。键,NULL),
elts[i].val);
}
归还新的;
}

不幸的是,这似乎在任何地方都没有记录。

我没有答案,但他们的
LA-U
东西让人觉得他们的“状态”在处理过程中受到了相当松散的控制。FWIW我总是尝试确保任何可能意外递归的规则都可以在处理过程中处于最后一个,这样我就可以使用
[L]
,并且知道它不会无意触发任何事件。mod_rewrite[L]标志在全局规则文件和单个.htaccess文件中的行为不同。在.htaccess文件中,[L]循环回到开头,以确保没有进一步的更改—如果出现递归问题,这正是您不希望看到的。如果您真的希望.htaccess中的配方停止而没有任何递归的机会,请改用[END]标志。这样您可以使用变量,但必须使用重定向前缀来查找它。你可以理解他们为什么会这样做。它模拟具有范围解析的动态作用域。在递归上下文中,您可以请求重定向\u FOO以查看父环境中是否存在FOO变量。大概是重定向\u重定向\u FOO。。。这可以作为一个很好的方法来区分您是在内部重定向后还是直接到达某个规则。我一定要试试这个。该死的有用的知识;谢谢 [.../initial] (3) [perdir /.../test/] strip per-dir prefix: /.../test/stuff -> stuff [.../initial] (3) [perdir /.../test/] applying pattern '(.*)' to uri 'stuff' [.../initial] (4) [perdir /.../test/] RewriteCond: input='' pattern='!=true' => matched [.../initial] (4) [perdir /.../test/] RewriteCond: input='/test/stuff' pattern='(.*)/' => matched [.../initial] (2) [perdir /.../test/] rewrite 'stuff' -> '/test/foo.php?original=stuff' [.../initial] (5) setting env variable 'did_rewrite' to 'true' [.../initial] (3) split uri=/test/foo.php?original=stuff -> uri=/test/foo.php, args=original=stuff [.../initial] (1) [perdir /.../test/] internal redirect with /test/foo.php [INTERNAL REDIRECT] [.../initial/redir#1] (3) [perdir /.../test/] strip per-dir prefix: /.../test/foo.php -> foo.php [.../initial/redir#1] (3) [perdir /.../test/] applying pattern '(.*)' to uri 'foo.php' [.../initial/redir#1] (4) [perdir /.../test/] RewriteCond: input='' pattern='!=true' => matched [.../initial/redir#1] (4) [perdir /.../test/] RewriteCond: input='/test/foo.php' pattern='(.*)/' => matched [.../initial/redir#1] (2) [perdir /.../test/] rewrite 'foo.php' -> '/test/foo.php?original=foo.php' ...
static apr_table_t *rename_original_env(apr_pool_t *p, apr_table_t *t)
{
    const apr_array_header_t *env_arr = apr_table_elts(t);
    const apr_table_entry_t *elts = (const apr_table_entry_t *) env_arr->elts;
    apr_table_t *new = apr_table_make(p, env_arr->nalloc);
    int i;

    for (i = 0; i < env_arr->nelts; ++i) {
        if (!elts[i].key)
            continue;
        apr_table_setn(new, apr_pstrcat(p, "REDIRECT_", elts[i].key, NULL),
                  elts[i].val);
    }

    return new;
}