【问题标题】:htaccess If...Else always selects Elsehtaccess If...Else 总是选择 Else
【发布时间】:2017-01-20 13:57:44
【问题描述】:

我在 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

【问题讨论】:

  • 这里没有看到 %{ENV: 是一个有效的表达式 ~ httpd.apache.org/docs/2.4/expr.html。虽然有env 功能
  • @Phil 感谢您的提示。该页面上的文档语言很难理解,但我认为你让我走上了正确的轨道
  • @Phil %{ENV: 也是有效的。将扩展为"%{" funcname ":" funcargs "}"
  • @hjpotter92 你能链接到一些文档吗?
  • @Phil 您提供的链接,在 Bachus Naur 语法部分下,请参阅 variable 的扩展。页面下方还提供了函数列表。

标签: apache .htaccess environment-variables apache2.4


【解决方案1】:

如果您在 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>

【讨论】:

    【解决方案2】:

    我可以让它工作的唯一方法是在.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 之前对其进行了评估)

    【讨论】:

    • 请说明您的意思是您做了一个或另一个,或者您必须同时做两个(.conf.htaccess 设置)。请同时显示&lt;If ...&gt; 中的表达式。
    • 不幸的是没有If,所以这种方法的可用性非常有限
    【解决方案3】:

    不使用表达式,即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 版本,即&lt;2.4


    编辑:

    在您的 Apache 配置或 vhost 配置中有这个变量初始化:

    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 配置中声明 env 变量,因为 .htaccess 在 Apache/vhost 配置之后加载,并且在同一 .htaccess 中设置的 env 变量无法在 if/else 表达式中进行评估。

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

    【讨论】:

    • 谢谢。我正在使用&lt;if&gt;&lt;else&gt;,因为我想为两个不同的环境包装一大块许多指令。我在块中使用了SetEnv,这只是我从我的 PHP 脚本中检查执行了哪个分支的快速方法。我实际上不需要设置TEST_VAR。它是一组指令的占位符。
    • 很好解释。它在我的开发机器上工作,但在服务器上我收到错误/path/.htaccess: Invalid command 'SetEnv', perhaps misspelled or defined by a module not included in the server configuration 所以要在 htaccess 中设置TEST_VAR 我做了SetEnvIf Host ^ TEST_VAR=if_branch。谢谢
    • 这里的问题是 本身中引用的变量在解析 htaccess 文件后立即解析。因此,任何可以在 htaccess 中配置的模块都在 之后运行。 mod_setenvif 有点独特之处在于,当您将其放在任何配置部分之外时,它可以尽早运行其代码。几乎没有其他模块可以做到这一点。我认为这里最好的模式是尝试插入将表达式作为条件的指令
    • @anubhava。我专门寻找这个:httpd.apache.org/docs/current/mod/core.html#if。但是我能够在您链接的页面中找到它。感谢您的帮助。
    • 更详细的文档请参考:httpd.apache.org/docs/current/expr.html
    【解决方案4】:

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

    设置一个内部环境变量,然后可用于 Apache HTTP Server 模块,并传递给 CGI 脚本和 SSI 页面。

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

    <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 页面上还列出了以下警告:

    SetEnv 指令在请求处理过程中运行延迟的含义 SetEnvIfRewriteCond 等指令不会看到 用它设置的变量。

    【讨论】:

    • 感谢您的意见和测试。这是否意味着我不能使用基于环境变量的If/Else 分支?特别是在同一 .htaccess 中设置的 var。也许它可以与通过SetEnvIf 设置的变量一起使用?
    • @BeetleJuice 不在同一个上下文中,不!您必须将环境设置在至少比 &lt;if&gt; 指令位置高一级的上下文中。
    • 查看@anubhava 答案下的评论,了解这里发生了什么独特的事情。这不是封闭部分的问题,因为这不会影响执行时间。
    猜你喜欢
    • 2020-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-27
    • 2017-09-11
    • 1970-01-01
    • 2016-05-10
    相关资源
    最近更新 更多