我有一个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)
放到一个变量中,并且只使用这个变量?在目前的方法中,添加一种新语言意味着重写许多规则。
1条答案
按热度按时间2hh7jdfx1#
我能不能把语言列表
(en|us|uk|fr|de)
放到一个变量中,并且只使用这个变量?您不能直接在正则表达式中使用“变量”,因为Apache使用的regex引擎(PCRE)不支持这种类型的语法。
你可以让正则表达式更通用,匹配任意两个小写字母,并依靠你的应用程序来验证语言代码(无论如何你都应该这样做)。这样,当你添加一种新语言时,你根本不需要更新你的Apache配置(这将是更好的)。例如:
此外,如果您没有任何其他非语言URL可以合法地将两个小写字母作为第一个路径段,那么您也可以在
.htaccess
中验证这一点,并在现有语言规则之前添加一个额外的规则。例如:上述规则规定...如果在第一个路径段中传递了2个小写字母,并且这2个字符序列与规定的语言代码之一不匹配,则触发404。不处理后续规则。
这允许你在文件的顶部声明一次有效的语言代码,但是这限制了你的URL结构(没有额外的规则/条件),因为你不能有
/xx/...
形式的URL,其中xx
不是语言代码。**更新:**使用“变量...”
对此有另一种想法...您可能会使用“变量”,但您需要向每个规则添加 condition(
RewriteCond
指令),以便将请求的URL路径中的语言代码与(环境)变量中的语言代码“列表”进行比较。例如:
分配给
LANG_CODES
环境变量的值只是一个由任何唯一字符分隔的语言代码字符串。我使用了 * 管道 *(竖线)作为分隔符,就像regex交替一样,但这不是一个regex。正则表达式
([a-z]{2}).*@\1?$
使用内部反向引用(\1
)来匹配URL路径中传递的语言代码与LANG_CODES
字符串中的语言代码。额外的复杂性是可能根本没有语言代码(因此需要尾随?$
)。这个正则表达式不是特别有效,因为它可能涉及大量的回溯(尽管在这种情况下这是相对次要的问题)。不用说,如果你有很多规则,这可能会增加很多“膨胀”。如果重写引擎发生任何“循环”,env var的使用可能会有问题,因为env var可能会被“重命名”(其他规则可能需要修改以允许这种情况或完全防止循环)。
这种“更新”实际上只是“学术”兴趣(尽管它确实避免了与任何非语言URL的冲突,这些URL的初始路径段恰好只有两个字符)。
RewriteRule
pattern 中的第一个组设为非捕获,那么语言代码将在$1
反向引用中可用,而不是$2
。例如:作为一般规则,您感兴趣的第一个regex group 之前的任何regex group 都应该是非捕获的,因此您感兴趣的捕获组总是以
$1
开头。