.htaccess htaccess -在规则中使用自定义变量

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

我有一个htaccess文件,里面有这样的内容:

RewriteRule ^((en|us|uk|fr|de)/)?([0-9\-.]+);([0-9\-.]+)$ index.php?l=$2&t=$3;$4 [QSA,L]
RewriteRule ^((en|us|uk|fr|de)/)?([A-Za-z\-]+)$ index.php?l=$2&t=$3 [QSA,L]

和许多类似的行。而且,在所有规则中,语言可能根本不存在。
我能不能把语言列表(en|us|uk|fr|de)放到一个变量中,并且只使用这个变量?在目前的方法中,添加一种新语言意味着重写许多规则。

2hh7jdfx

2hh7jdfx1#

我能不能把语言列表(en|us|uk|fr|de)放到一个变量中,并且只使用这个变量?
您不能直接在正则表达式中使用“变量”,因为Apache使用的regex引擎(PCRE)不支持这种类型的语法。
你可以让正则表达式更通用,匹配任意两个小写字母,并依靠你的应用程序来验证语言代码(无论如何你都应该这样做)。这样,当你添加一种新语言时,你根本不需要更新你的Apache配置(这将是更好的)。例如:

RewriteRule ^(([a-z]{2})/)?([0-9\-.]+);([0-9\-.]+)$ index.php?l=$2&t=$3;$4 [QSA,L]

此外,如果您没有任何其他非语言URL可以合法地将两个小写字母作为第一个路径段,那么您也可以在.htaccess中验证这一点,并在现有语言规则之前添加一个额外的规则。例如:

# Validate language code in first path segment
RewriteCond $1 !^(en|us|uk|fr|de)$
RewriteRule ^([a-z]{2})/ - [R=404]

上述规则规定...如果在第一个路径段中传递了2个小写字母,并且这2个字符序列与规定的语言代码之一不匹配,则触发404。不处理后续规则。
这允许你在文件的顶部声明一次有效的语言代码,但是这限制了你的URL结构(没有额外的规则/条件),因为你不能有/xx/...形式的URL,其中xx不是语言代码。

**更新:**使用“变量...”

对此有另一种想法...您可能会使用“变量”,但您需要向每个规则添加 conditionRewriteCond指令),以便将请求的URL路径中的语言代码与(环境)变量中的语言代码“列表”进行比较。
例如:

# Define "list" of valid language codes
RewriteRule ^ - [E=LANG_CODES:en|us|uk|fr|de]

RewriteCond %{ENV:LANG_CODES}@$2 ([a-z]{2}).*@\1?$
RewriteRule ^(([a-z]{2})/)?([0-9\-.]+);([0-9\-.]+)$ index.php?l=$2&t=$3;$4 [QSA,L]

分配给LANG_CODES环境变量的值只是一个由任何唯一字符分隔的语言代码字符串。我使用了 * 管道 *(竖线)作为分隔符,就像regex交替一样,但这不是一个regex。
正则表达式([a-z]{2}).*@\1?$使用内部反向引用(\1)来匹配URL路径中传递的语言代码与LANG_CODES字符串中的语言代码。额外的复杂性是可能根本没有语言代码(因此需要尾随?$)。这个正则表达式不是特别有效,因为它可能涉及大量的回溯(尽管在这种情况下这是相对次要的问题)。
不用说,如果你有很多规则,这可能会增加很多“膨胀”。如果重写引擎发生任何“循环”,env var的使用可能会有问题,因为env var可能会被“重命名”(其他规则可能需要修改以允许这种情况或完全防止循环)。
这种“更新”实际上只是“学术”兴趣(尽管它确实避免了与任何非语言URL的冲突,这些URL的初始路径段恰好只有两个字符)。

  • 旁白:* 我会将RewriteRulepattern 中的第一个组设为非捕获,那么语言代码将在$1反向引用中可用,而不是$2。例如:
RewriteRule ^(?:([a-z]{2})/)?([0-9\-.]+);([0-9\-.]+)$ index.php?l=$1&t=$2;$3 [QSA,L]

作为一般规则,您感兴趣的第一个regex group 之前的任何regex group 都应该是非捕获的,因此您感兴趣的捕获组总是以$1开头。

相关问题