使用<If> 部分的一些替代方法,因为<If> is not without its caveats。
- 当条件匹配(或不匹配)时跳过指令
- 在 URL 前加上主机名(以匹配)
- 为每个主机单独的
.htaccess 配置文件
(旁白:你真的想要一个不区分大小写的 - NC - 匹配吗?)
1。当条件匹配(或不匹配)时跳过指令
当规则(或条件)不匹配时,您可以跳过(S 标志)任意数量的指令。 IE。如果您跳过HTTP_HOST 不是domain1.com 时遵循的规则,则仅当HTTP_HOST 是domain1.com 时才会处理以下规则。
例如:
# Skip the following 4 rules when the host is not "domain1.com"
RewriteCond %{HTTP_HOST} !=domain1.com
RewriteRule ^ - [S=4]
# Only processed when the HTTP_HOST is equal to "domain1.com"
#main pages
RewriteRule ^members/$ /index.php?pageid=2 [NC,L]
RewriteRule ^contact/$ /index.php?pageid=3 [NC,L]
RewriteRule ^affiliates/$ /index.php?pageid=4 [NC,L]
#blog articles
RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
# --------------------------------------------------------------------
# Skip the following 5 rules when the host is not "domain2.com"
RewriteCond %{HTTP_HOST} !=domain2.com
RewriteRule ^ - [S=5]
# Only processed when the HTTP_HOST is equal to "domain2.com"
#main pages
RewriteRule ^about/$ /index.php?pageid=2 [NC,L]
RewriteRule ^press-kit/$ /index.php?pageid=3 [NC,L]
RewriteRule ^contact/$ /index.php?pageid=4 [NC,L]
RewriteRule ^affiliates/$ /index.php?pageid=5 [NC,L]
#blog articles
RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
虽然这种方法的一个明显警告是,在添加或删除任何规则时,您需要小心更新 S=<number> 标志。
您显然可以颠倒逻辑,在顶部放置一个看起来像目录的东西。例如:
RewriteCond %{HTTP_HOST} =domain1.com
RewriteRule ^ - [S=2]
RewriteCond %{HTTP_HOST} =domain2.com
RewriteRule ^ - [S=5]
RewriteCond %{HTTP_HOST} =domain3.com
RewriteRule ^ - [S=9]
# --------------------------------------------------------------------
# domain1.com
#main pages
RewriteRule ^members/$ /index.php?pageid=2 [NC,L]
RewriteRule ^contact/$ /index.php?pageid=3 [NC,L]
RewriteRule ^affiliates/$ /index.php?pageid=4 [NC,L]
#blog articles
RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
# --------------------------------------------------------------------
# domain2.com
#main pages
RewriteRule ^about/$ /index.php?pageid=2 [NC,L]
RewriteRule ^press-kit/$ /index.php?pageid=3 [NC,L]
RewriteRule ^contact/$ /index.php?pageid=4 [NC,L]
RewriteRule ^affiliates/$ /index.php?pageid=5 [NC,L]
#blog articles
RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
虽然“跳过”规则可能更容易出错,因为您可能需要在添加或删除规则时更新多个规则,具体取决于这些规则所在的位置。
2。用主机名前缀 URL(以匹配)
或者,您可以(临时)在 URL 路径前加上主机名,并在随后的规则中与此匹配。这避免了所有后续规则中的附加 RewriteCond 指令。
例如:
# Prefix URL-path with HTTP_HOST if not already prefixed / No "L" flag
RewriteCond %{HTTP_HOST}@$1 !^([a-z.-]+)@\1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) %{HTTP_HOST}/$1
# --------------------------------------------------------------------
# domain1.com
#main pages
RewriteRule ^domain1\.com/members/$ /index.php?pageid=2 [NC,L]
RewriteRule ^domain1\.com/contact/$ /index.php?pageid=3 [NC,L]
RewriteRule ^domain1\.com/affiliates/$ /index.php?pageid=4 [NC,L]
#blog articles
RewriteRule ^domain1\.com/welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
# --------------------------------------------------------------------
# domain2.com
#main pages
RewriteRule ^domain2\.com/about/$ /index.php?pageid=2 [NC,L]
RewriteRule ^domain2\.com/press-kit/$ /index.php?pageid=3 [NC,L]
RewriteRule ^domain2\.com/contact/$ /index.php?pageid=4 [NC,L]
RewriteRule ^domain2\.com/affiliates/$ /index.php?pageid=5 [NC,L]
#blog articles
RewriteRule ^domain2\.com/welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
这避免了额外的RewriteCond 指令,但是,它要求您在每种情况下都为匹配的 URL 路径加上域的前缀。与上面第一个示例中使用 S 标志相比,出错的可能性更小。
在上面的示例中,对于任何不直接映射到文件或未重写为/index.php?pageid=<number> 的 URL,主机名在请求末尾仍保留在 URL 路径的前缀。这将导致 404。
如果您特别想删除 hostname 前缀(也许您在错误文档中使用 $_SERVER['REDIRECT_URL'] 变量,而不是 $_SERVER['REQUEST_URI']),那么您可以通过引入额外的环境变量(我们称之为FINISHED)并在末尾去掉这个前缀。
例如,修改第一条规则以检查FINISHED env var(最初不存在)并在末尾引入一条新规则,删除前缀并设置 env var。如果没有FINISHED env var,我们将陷入“未知 URL”的重写循环,因为它会重复添加前缀并删除 URL 路径上的主机名。
# Prefix URL-path with HTTP_HOST if not already prefixed and not FINISHED / No "L" flag
RewriteCond %{ENV:FINISHED} ^$
RewriteCond %{HTTP_HOST}@$1 !^([a-z.-]+)@\1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) %{HTTP_HOST}/$1
# :
# : Directives for each domain go here (as above)
# :
# Tidy up - remove the HTTP_HOST prefix and set FINISHED env var
RewriteCond %{HTTP_HOST}@$1 ^([a-z.-]+)@\1/(.*)
RewriteRule (.*) %2 [E=FINISHED:1,L]
3。为每个主机单独的 .htaccess 配置文件
另一种可能更适合单独域和本质上单独的网站(尽管可能是“通用”引擎)的这种特殊情况的替代方法是为每个单独的(单独的).htaccess 文件网站。
具体配置方式可能取决于您配置文件结构的方式,但是,这可以增加站点之间的分离度,甚至可以在两个或多个站点之间共享配置(如果您愿意)。您可能拥有仅与正在访问的网站相关的资源 - 但您可能已经拥有类似的东西。
例如...
- 您仍将在文档根目录中拥有“master”
.htaccess 文件(假设您为所有域共享一个公共根目录)。
- 为每个主机创建一个子目录。例如。
/domain1.com,在每个子目录中,您只有一个用于该域的 .htaccess 文件。
文件结构:
/
domain1.com/
.htaccess
domain2.com/
.htaccess
.htaccess
index.php
/.htaccess
根.htaccess 文件随后会将请求路由到所请求主机的相应子目录。
RewriteEngine On
# If the request is already for index.php in the document root then DONE
RewriteRule ^index\.php$ - [L]
# Rewrite all requests that don't map to files to the appropriate domain subdirectory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) %{HTTP_HOST}/$1 [L]
/domain1.com/.htaccess
然后每个域的 .htaccess 文件只包含该域的指令,并将请求重写回文档根目录中的“通用”/index.php 文件以呈现请求。
重写指令采用与上述相同的“正常”格式。
# domain1.com
RewriteEngine On
# Optional - If this subdirectory is accessed directly then redirect back to the root
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) /$1 [R=301,L]
#main pages
RewriteRule ^members/$ /index.php?pageid=2 [NC,L]
RewriteRule ^contact/$ /index.php?pageid=3 [NC,L]
RewriteRule ^affiliates/$ /index.php?pageid=4 [NC,L]
#blog articles
RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
无论如何,值得深思。其中一些归结为您如何构建应用程序,而不是严格地“通过 RewriteCond 对 RewriteRule 进行分组”。如果您想进一步解释任何“位”,请直接说。