htaccess If...Else 总是选择 Else

htaccess If...Else always selects Else

我在httpd-vhosts.conf

中设置了一个环境变量
SetEnv EARLY_VAR 1

我尝试根据它在 .htaccess

中的值设置特殊规则
<If "%{ENV:EARLY_VAR} == '1'">
   SetEnv TEST_VAR  if_branch
</If>
<Else>
    SetEnv TEST_VAR  else_branch
</Else>

我希望 TEST_VAR 环境变量等于 if_branch。在PHP

var_dump(getenv('EARLY_VAR')); // string '1'
var_dump(getenv('TEST_VAR')); // string 'else_branch'

我还尝试在 If/Else 上方的 .htaccess 中设置 EARLY_VAR,同时使用 SetEnvSetEnvIf。始终执行 Else 分支。

这是为什么?

Apache 2.4

不使用表达式,即 if/else 指令,您可以这样做:

# set EARLY_VAR to 1
SetEnvIf Host ^ EARLY_VAR=1

# if EARLY_VAR is 1 then set TEST_VAR to if_branch
SetEnvIf EARLY_VAR ^1$ TEST_VAR=if_branch

# if EARLY_VAR is NOT 1 then set TEST_VAR to else_branch
SetEnvIf EARLY_VAR ^(?!1$) TEST_VAR=else_branch

这将适用于更旧的 Apache 版本,即 <2.4


编辑:

在你的 Apache 配置或虚拟主机配置中有这个变量初始化:

SetEnvIf Host ^ EARLY_VAR=5

然后在您的 .htaccess 中您可以使用:

<If "env('EARLY_VAR') == '5'">
   SetEnv TEST_VAR if_branch
</If>
<Else>
   SetEnv TEST_VAR else_branch
</Else>

之所以需要在 Apache/vhost 配置中声明环境变量,是因为 .htaccess 在 Apache/vhost 配置之后加载,并且在相同的 .htaccess 中设置的环境变量在 if/else 中不可用于评估表达式。

此外,请注意,重要的是使用 SetEnvIf 而不是 SetEnv 以使这些变量可用于 if/else 表达式。

查看 SetEnv directive 的文档,我注意到:

Sets an internal environment variable, which is then available to Apache HTTP Server modules, and passed on to CGI scripts and SSI pages.

这意味着环境随后可供其他模块使用。而 <if> 指令是由核心提供的。如果您在 <if> 子句期间尝试查看环境是否为空,则可以确认这一点:

<If "-z %{ENV:EARLY_VAR}">
   SetEnv TEST_VAR  if_branch
</If>

<If "-z env('EARLY_VAR')">
   SetEnv TEST_VAR  if_branch
</If>

两者都会给你:

string(1) "1" string(9) "if_branch" 

在你的 PHP.


Apache 的 environment variables wiki/docs 页面上还列出了以下警告:

The SetEnv directive runs late during request processing meaning that directives such as SetEnvIf and RewriteCond will not see the variables set with it.

我唯一能让它工作的方法是在 .conf.htaccess 中使用 SetEnvIf:

我在 .conf

中只使用了这个
SetEnvIf Server_Addr ^ EARLY_VAR=1

然后 .htaccess 中只有这个:

SetEnvIf EARLY_VAR ^ TEST_VAR=else_branch
SetEnvIf EARLY_VAR ^1$ TEST_VAR=if_branch

(没有 If 指令。无论我在 If 内尝试过什么,它似乎都是在设置 EARLY_VAR 之前评估的)

如果您发现 Apache 配置中的 SetEnv 和 SetEnvIf 有问题。

httpd.conf文件中设置变量如下

SetEnvIf Host ".*" EARLY_VAR=1
SetEnvIf Host eval EARLY_VAR=1
SetEnvIf Host dev EARLY_VAR=1

它在所有类型的服务器中分配值(production ,evaluation or development)

现在您可以在 .htaccess 文件 中使用您的变量。

<IF "%{ENV:EARLY_VAR} == 1">
    SetEnv TEST_VAR if_value
</IF>
<ELSE>
    SetEnv TEST_VAR else_value
</ELSE>