在RewriteRule匹配中使用环境变量-易于维护且体积更小

时间:2019-03-20 13:46:04

标签: .htaccess mod-rewrite

对于一个具有许多不同目录结构的非常老的站点,我需要进行大量重写。大约需要进行140次重定向,这是结构示例:

# First file set to first destination
RewriteRule ^(dir-one|dir-two|dir-three)\/(file-one|file-two|file-three)\/?$ /destination-one [R=301,L]

# Second file set to second destination
RewriteRule ^(dir-one|dir-two|dir-three)\/(file-four|file-five|file-six)\/?$ /destination-two [R=301,L]

# Third file set to third destination
RewriteRule ^(dir-one|dir-two|dir-three)\/(file-seven|file-eight|file-nine)\/?$ /destination-three [R=301,L]

# etc etc... Same sort of thing another 137 times!

如您所见,初始目录匹配(dir-one|dir-two|dir-three)中有很多重复信息。

我想-如果可能的话,使目录列表易于更新,并想知道环境变量是否可以工作。这是我尝试过的:

# setting the dir names in the ENV:
RewriteRule .* - [E=DIRS:"dir-one|dir-two|dir-three"]

# First file set to first destination
RewriteRule ^(%{ENV:DIRS})\/(file-one|file-two|file-three)\/?$ /destination-one [R=301,L]

# Second file set to second destination
RewriteRule ^(%{ENV:DIRS})\/(file-four|file-five|file-six)\/?$ /destination-two [R=301,L]

# Third file set to third destination
RewriteRule ^(%{ENV:DIRS})\/(file-seven|file-eight|file-nine)\/?$ /destination-three [R=301,L]

这不起作用。我知道已设置ENV(请参见下面的屏幕截图),但是RewriteRules中似乎没有使用它们。我在做什么错,这是否有可能,还有更好的方法吗?

如果这行得通,我可能会扩展它以将文件集另存为ENV,这样文件集也可以在一个地方更新。

谢谢!

Screeny showing Env Vars in phpinfo

一些澄清...

我的示例没有显示我正在努力实现的目标。这是一个更“现实世界”的示例:

# What I have now. Note the repeated 'sections|categories|areas' part:

RewriteRule ^(sections|categories|areas)\/(car|plane|train)\/?$ /transport [R=301,L]
RewriteRule ^(sections|categories|areas)\/(pig|cow|goat|kangaroo)\/?$ /animals [R=301,L]
RewriteRule ^(sections|categories|areas)\/(cheese|fish|turnips)\/?$ /food [R=301,L]
# etc etc... Same sort of thing another 137 times!
# What I'm hoping is possible. It will allow me to add or edit the
# first match (sections|categories|areas) in one place and not 140 places. 

RewriteRule .* - [E=DIRS:"sections|categories|areas"]

RewriteRule ^(%{ENV:DIRS})\/(car|plane|train)\/?$ /transport [R=301,L]
RewriteRule ^(%{ENV:DIRS})\/(pig|cow|goat|kangaroo)\/?$ /animals [R=301,L]
RewriteRule ^(%{ENV:DIRS})\/(cheese|fish|turnips)\/?$ /food [R=301,L]

因此,每次重写的第一个匹配项始终相同。第二个匹配项和目标之间有不同的映射。即所有车辆都去/transport,所有动物都去/animals等,等等。

我在这里的主要目的是避免将第一场比赛重复140次。如果我的目标很愚蠢,请这么说:)

谢谢!

1 个答案:

答案 0 :(得分:2)

ENV中的RewriteCond匹配,而不像RewriteRule中的匹配:

RewriteRule ^(dir-one|dir-two|dir-three)/(.*)$ - [E=DIRS:$1]

RewriteCond %{ENV:DIRS} ^dir-one
RewriteRule ^([^\/]+)\/(file-one|file-two|file-three)\/?$ /destination-one [R=301,L]

RewriteCond %{ENV:DIRS} ^dir-two
RewriteRule ^([^\/]+)\/(file-four|file-five|file-six)\/?$ /destination-two [R=301,L]

RewriteCond %{ENV:DIRS} ^dir-three
RewriteRule ^([^\/]+)\/(file-seven|file-eight|file-nine)\/?$ /destination-three [R=301,L]

此外,如果您只想将它​​们重定向到新的目录,并且新旧uri之间没有关系(如我所见),请使它们像这样:

RewriteRule ^(dir-one|dir-two|dir-three)/(.*)/?$ - [E=DIRS:$1-$2]

RewriteCond %{ENV:DIRS} ^dir-one\-(file-one|file-two|file-three)
RewriteRule ^  /destination-one [R=301,L]

RewriteCond %{ENV:DIRS} ^dir-two\-(file-four|file-five|file-six)
RewriteRule ^  /destination-two [R=301,L]

RewriteCond %{ENV:DIRS} ^dir-three\-(file-seven|file-eight|file-nine)
RewriteRule ^    /destination-three [R=301,L]

更新:

根据您的更新,尝试以下操作:

RewriteEngine on

RewriteRule ^(sections|categories|areas)/(.*)/?$   -   [E=DIRS:$1-$2]

RewriteCond %{ENV:DIRS} ^(.+)\-(car|plane|train)
RewriteRule ^  /transport  [R=301,L]

RewriteCond %{ENV:DIRS} ^(.+)\-(pig|cow|goat|kangaroo)
RewriteRule ^  /animals  [R=301,L]

RewriteCond %{ENV:DIRS} ^(.+)\-(cheese|fish|turnips)
RewriteRule ^  /food  [R=301,L]

注意:清除浏览器缓存,然后进行测试