当URL以目录开头时,在.htaccess中设置环境变量

vs3odd8k  于 2022-11-16  发布在  其他
关注(0)|答案(1)|浏览(135)

我尝试在我的.htaccess中基于URL的第一个子目录设置一个环境变量。只要URL包含dira作为第一个子目录,它就应该将我的变量(myvar)设置为值123。例如,这些URL应该工作:

test.com/dira
test.com/dira/
test.com/dira/b
test.com/dira/b/
test.com/dira/b/random.html
test.com/dira/b/2
test.com/dira/b/2/
test.com/dira/b/2/and-so-in-into-infinity

应忽略任何其他URL,例如:

test.com
test.com/
test.com/dirb
test.com/dirc/123/456/789/blah
test.com/123/dira/
test.com/dirz/

我在我的.htaccess中尝试了所有这些规则,但都没有成功:

RewriteRule ^dira(.*)$ [E=myvar:123]
RewriteRule ^dira/(.*)$ [E=myvar:123]
RewriteRule ^dira/? [E=myvar:123]
RewriteRule ^dira/?$ [E=myvar:123]

在每种情况下,myvar都没有设置。所以我的问题是,在第一个子目录之后用什么语法来通配符所有内容?谢谢。

ut6juiuv

ut6juiuv1#

RewriteRule ^dira(.*)$ [E=myvar:123]
RewriteRule ^dira/(.*)$ [E=myvar:123]
RewriteRule ^dira/? [E=myvar:123]
RewriteRule ^dira/?$ [E=myvar:123]

缺少 substitution 字符串(第二个参数),因此这些指令实际上都没有设置环境变量。[E=myvar:123]被视为 substitution 字符串(第二个参数),因此将导致格式相当不正确的内部重写。
它应该是这样的:

RewriteRule ^dira($|/) - [E=myvar:123]

请注意,单连字符(-)作为替换字符串(第二个参数),表示“无替换”。
正则表达式^dira($|/)匹配包含dira作为第一个 * 完整 * 路径段的任何URL路径。例如,它匹配diradira/dira/anything,但不匹配dirasomething
但是,.htaccess文件中的其他指令会导致其他“问题”...

RewriteRule ^([^/\.]+)/?$ index.php?acid={ENV:myvar} [L]

(* 旁白:* 那应该是%{ENV:myvar}-你漏掉了%前缀。)
如果这是.htaccess文件中唯一的其他规则,那么当请求/dira/something时,myvar env var应该成功设置,而不是/dira/dira/(因为/dira/dira/都被上述规则内部重写了)。
原因是,当匹配时,上述RewriteRule触发重写引擎的第二遍,(在.htaccess中使用时)。第二次传递会导致使用REDIRECT_前缀重命名已设置的任何环境变量。例如,myvar将变为REDIRECT_myvarmyvar不会因为index.php与您的规则不匹配,所以在第二次传递时(重新)设置。
您可以:

  • 修改上面的RewriteRule指令(在内部重写请求)以防止重写引擎的第二次传递。这可以通过将L标志更改为END(需要Apache 2.4)来完成。例如:
RewriteRule ^([^/.]+)/?$ index.php?acid=%{ENV:myvar} [END]

注意,我通过包含%前缀更正了env var引用,并且在正则表达式字符类中使用时不需要反斜杠转义文字点。
然而,你需要注意你将来添加的规则,以防止重写引擎的循环。有时重写引擎的循环特性是可取的。

  • 检查PHP代码中的myvar * 和 * REDIRECT_myvar(即$_SERVER['REDIRECT_myvar'])。由于不是所有启动dira的请求都被上述规则重写,因此您将在不同的时间设置myvarREDIRECT_myvar。具体来说,/dira/dira/将导致REDIRECT_myvar被设置,并且/dira/something将具有期望的myvar设置(因为它未被重写)。

相关问题