如何在 .htaccess 文件中定义变量并使用它?

20

我为我的网站定义了一个.htaccess文件,其中包含以下代码:

RewriteEngine on
RewriteBase /

RewriteRule ^bit_auth\/?(.*)$ /cig/base3/auth/$1 [R=301,NC,L]
RewriteCond $1 !^(index\.php|images|robots\.txt|assets|themes|includes)
RewriteRule ^(.*)$ /cig/base3/index.php/$1 [L]

我希望像这样将我的网站根路径保存在一个变量中

RewriteEngine on
RewriteBase /
SetEnv BASE_PATH "/cig/base3"

RewriteRule ^bit_auth\/?(.*)$ %{ENV:BASE_PATH}/auth/$1 [R=301,NC,L]
RewriteCond $1 !^(index\.php|images|robots\.txt|assets|themes|includes)
RewriteRule ^(.*)$ %{ENV:BASE_PATH}/index.php/$1 [L]
因为我可能需要在以后的更多代码中使用BASE_PATH值,而且它可能会改变,我不想每次都在我的htaccess文件中搜索和替换。 但是当我使用上面的代码时,在htaccess文件中%{ENV:BASE_PATH}返回了一个空值,而不是期望的/cig/base3,但是在PHP中,当我使用以下代码调用它时:
<?php $specialPath = getenv('BASE_PATH'); var_dump($specialPath)?>

它显示了/cig/base3的正确值。

我的代码有什么问题,我该如何解决?


4
Apache加载/运行模块的顺序存在一个小问题 - mod_rewrite模块总是在SetEnv模块之前运行,因此您不能使用SetEnv来设置要在RewriteRule中使用的环境变量;但是,您可以使用RewriteRule设置变量,例如:RewriteRule .* - [E=BASE_PATH:/cig/base3] - CD001
@CD001,我不是很明白为什么要这样使用,但当我将您的代码插入我的htaccess文件中时,它按预期工作。您有更多描述/细节的参考资料和非经验用户的示例吗?或者请详细说明一下。 - Mojtaba Rezaeian
1个回答

16

因为SetEnv指令还未被处理,所以你不能这样使用它。

该指令设置的内部环境变量是在大多数早期请求处理指令运行之后设置的,例如访问控制和URI到文件名映射。如果您要设置的环境变量是作为此早期处理阶段的输入(例如RewriteRule指令),则应改用SetEnvIf设置环境变量。

你需要使用setenvif而不是SetEnv

因此,你可以像下面这样操作:

SetEnvIf Request_URI "^.*" base_path=/cig/base3

http://httpd.apache.org/docs/2.2/mod/mod_setenvif.html#setenvif


3
这就是我在评论中想表达的意思...我现在正在工作,所以没有时间写一个完整格式化的连贯答案 ;) SetEnvIf(与SetEnv不同)将在mod_rewrite之前运行 - 但您也可以使用mod_rewrite本身设置环境变量 - 两者都可以。 - CD001
但是两个答案都是正确的,我不明白为什么要用这些方式来做?哪一个更正确? - Mojtaba Rezaeian
3
@mrez.ir - 两种方法都可以完成相同的任务,只是方式不同 - 无论哪种方式,最终都会设置一个环境变量。如果我要在RewriteRules中使用该变量,我更喜欢通过RewriteRule来设置它...但实际上并没有太大关系。 - CD001
它会减慢原始的htaccess行为吗?我的意思是会加载两次某些内容吗? - Mojtaba Rezaeian
1
@mrez.ir .htaccess 只有在目录被扫描时才会被读取一次,但是 .htaccess 会在每个请求上被读取并进行相应的处理。因此,它不会比默认行为引入任何额外的延迟。 - Panama Jack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接