使RewriteRule可移植/相对于.htaccess文件的目录

3 apache .htaccess mod-rewrite redirect

我有以下RewriteRule使其可以将某人domain.com/somepage/?page=3重定向到301 domain.com/somepage/3/

RewriteCond %{THE_REQUEST} \?page=([0-9]+) [NC]
RewriteRule ^ /somepage/%1/? [R=301,L]
Run Code Online (Sandbox Code Playgroud)

这在目录中的.htaccess文件中somepage

现在,这个工作很好...但它是一个有点麻烦。我有大约十二个分页页面,所有页面都在各自的目录中。我只想将.htaccess文件复制到每个目录中,而不必担心编辑每个目录。例如,我也想domain.com/someotherpage/?page=3重定向到domain.com/someotherpage/3/,但是要做到这一点,我必须编辑相应的.htaccess文件并将其somepage部分更改为someotherpage

当我将整个站点复制到其他服务器时,也会引起问题。通常,站点位于根目录中。但是,当我在本地运行它时,我将整个站点放在一个名为的文件夹中dev。所以现在我必须遍历所有RewriteRules并将其从更改/somepage/%1//dev/somepage/%1。您可能会想到,这是令人难以置信的乏味。

因此,有没有一种方法可以更改它,以便它重定向到的路径是相对于.htaccess文件的,而不是从服务器的根目录开始的,因此我可以重复使用同.htaccess一遍而不更改它,从而也可以移动我的整个网站都进入dev目录,而无需更改任何内容?

谢谢。

anu*_*ava 5

您可以使用单独的规则获取动态捕获的重写库:

RewriteEngine On

RewriteCond $0#%{REQUEST_URI} ^([^#]*)#(.*)\1$
RewriteRule ^.*$ - [E=BASE:%2]

RewriteCond %{THE_REQUEST} \?page=(\d+) [NC]
RewriteRule ^ %{ENV:BASE}/%1/? [R=301,L]
Run Code Online (Sandbox Code Playgroud)

说明:

  • 您可以在您的系统中使用$0捕获自RewriteRuleRewriteCond因为mod_rewrite实际上是向后处理规则集。它RewriteRule从中的模式开始,如果匹配,则继续检查一个或多个RewriteCond
  • 所以你可以在看RewriteCond,在LHS(测试字符串)可以使用反向引用变量例如$1$2OR %1%2等,但RHS侧即条件字符串不能使用这些$1$2OR %1%2变量。
  • 在RHS条件部分中,我们只能使用内部参考,即我们在此条件下捕获的组。它们用表示\1\2等等。
  • 在您的RewriteCond第一个捕获组中([^#]*)。它由内部反向引用`\ 1表示。
  • 正如您可以指出的,该规则基本上是RewriteBase通过比较%{REQUEST_URI}和来动态查找的$0。的一个例子%{REQUEST_URI}将是/directory/foobar.php和实施例的$0用于同样的例子URI将是foobar.php^([^#]*)#(.*)\1$将差异放在第二个捕获的组%2或中\2。这将填充%2\2与值/directory/这是在设置环境变量稍后用于%{ENV:BASE}E=BASE:%2