Regex 将RewriteBase动态设置为当前文件夹路径

Regex 将RewriteBase动态设置为当前文件夹路径,regex,apache,.htaccess,mod-rewrite,url-rewriting,Regex,Apache,.htaccess,Mod Rewrite,Url Rewriting,有没有办法将RewriteBase设置为相对于主机根目录的当前文件夹(即.htaccess文件所在的文件夹)的路径 我有一个CMS,如果我将它移动到主机中的目录,它将不起作用,除非我将RewriteBase设置为相对于主机根目录的目录路径。我希望我的CMS只使用复制和粘贴,而不更改htaccess中的任何代码 更新: 例如: webroot - sub_directory - cms - .htaccess 在这种情况下,我应该在htaccess中编写:RewriteBase/ 如果我

有没有办法将RewriteBase设置为相对于主机根目录的当前文件夹(即.htaccess文件所在的文件夹)的路径

我有一个CMS,如果我将它移动到主机中的目录,它将不起作用,除非我将RewriteBase设置为相对于主机根目录的目录路径。我希望我的CMS只使用复制和粘贴,而不更改htaccess中的任何代码

更新: 例如:

webroot

 - sub_directory
 - cms
 - .htaccess
在这种情况下,我应该在htaccess中编写:
RewriteBase/

如果我将htaccess移动到sub_目录中,我应该将RewriteBase更改为:

RewriteBase/sub\u目录/

所以我想要像这样的东西


RewriteBase/%{current_folder}/

这里有一种方法可以在环境变量中获取
RewriteBase
,然后在其他重写规则中使用:

RewriteCond %{REQUEST_URI}::$1 ^(.*?/)(.*)::\2$
RewriteRule ^(.*)$ - [E=BASE:%1]
然后,您可以在规则中使用
%{ENV:BASE}
来表示
RewriteBase
,即:

#redirect in-existent files/calls to index.php
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteRule . %{ENV:BASE}/index.php [L]
说明: 此规则的工作原理是将
REQUEST\u URI
RewriteRule
看到的URL路径进行比较,该URL路径是
REQUEST\u URI
与前面的
RewriteBase
剥离的URL路径。不同之处在于
RewriteBase
并被放入
%{ENV:BASE}

  • 在重写条件下,LHS(测试字符串)可以使用反向引用变量,例如
    $1
    $2
    %1
    %2
    等,但RHS端,即条件字符串不能使用这些
    $1
    $2
    %1
    %2
    变量
  • 在RHS条件部分内,我们可以使用的唯一反向参考是内部反向参考,即我们在该条件本身中捕获的组。它们由
    \1
    \2
    等表示
  • RewriteCond
    中,第一个捕获的组是
    (.*?/)
    。它将由内部反向参考
    \1
    表示
  • 通过比较
    %{REQUEST\u URI}
    $1
    ,可以看出此规则基本上是动态查找
    RewriteBase
    %{REQUEST_URI}
    的示例将是
    /directory/foobar.php
    ,相同示例URI的
    $1
    示例将是
    foobar.php
    <代码>^(.*?/)(.*):\2$正在将差异放入第一个捕获的组
    %1
    \1
    。对于我们的示例,它将使用值
    /directory/
    填充
    %1
    \1
    ,该值稍后在
    E=BASE:%1
    中设置env变量
    %{env:BASE}
    时使用

我认为,公认的解决方案对我不起作用,但这确实:

长话短说:

RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond $0#%{REQUEST_URI} ([^#]*)#(.*)\1$
RewriteRule ^.*$ %2index.php [QSA,L]
在和的基础上,这里是我刚刚为自己想到的(还没有在生产中使用,也没有广泛测试)

让我们使用此示例URL,其中.htaccess位于当前的\u文件夹中:

http://localhost/path_to/current_folder/misc/subdir/file.xyz

文件系统:
/var/www/webroot/path\u to/current\u folder/.htaccess

Options +FollowSymLinks
RewriteEngine On
RewriteBase /

RewriteCond %{ENV:SUBPATH} ^$  # Check if variable is empty. If it is, process the next rule to set it.
RewriteRule ^(.*)$ - [ENV=SUBPATH:$1]
# SUBPATH is set to 'misc/subdir/file.xyz'

RewriteCond %{ENV:CWD} ^$
RewriteCond %{ENV:SUBPATH}::%{REQUEST_URI} ^(.*)::(.*?)\1$
RewriteRule ^ - [ENV=CWD:%2]
# CWD is set to '/path_to/current_folder/'

RewriteCond %{ENV:FILENAME} ^$
RewriteCond %{REQUEST_URI} ^.*/(.*)$
RewriteRule ^ - [ENV=FILENAME:%1]
# FILENAME is set to 'file.xyz'

# Check if /var/www/webroot/path_to/current_folder/misc/subdir/file.xyz exists.
# -f checks if a file exists, -d checks for a directory.
# If it exists, rewrite to /path_to/current_folder/misc/subdir/file.xyz and stop processing rules.
RewriteCond %{ENV:SUBPATH} ^.+$  # Ensure SUBPATH is not empty
RewriteCond %{DOCUMENT_ROOT}%{ENV:CWD}%{ENV:SUBPATH} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{ENV:CWD}%{ENV:SUBPATH} -d
RewriteRule ^.*$ %{ENV:CWD}%{ENV:SUBPATH} [END]

# Check if /var/www/webroot/path_to/current_folder/file.xyz exists.
# If it exists, rewrite to /path_to/current_folder/file.xyz and stop processing rules.
RewriteCond %{ENV:FILENAME} ^.+$
RewriteCond %{DOCUMENT_ROOT}%{ENV:CWD}%{ENV:FILENAME} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{ENV:CWD}%{ENV:FILENAME} -d
RewriteRule ^.*$ %{ENV:CWD}%{ENV:FILENAME} [END]

# Else, rewrite to /path_to/current_folder/index.html and stop processing rules.
RewriteRule ^.*$ %{ENV:CWD}index.html [END]
通过在apache中的
httpd.conf
中使用
LogLevel alert rewrite:trace6
,然后查看
error.log
,您可以查看正在发生的事情的详细信息

下面是关于以下两行的更多说明,我仍然觉得有点困惑

RewriteCond %{ENV:SUBPATH}::%{REQUEST_URI} ^(.*)::(.*?)\1$
RewriteRule ^ - [ENV=CWD:%2]
首先,双冒号
不是任何类型的运算符;它只是一个任意的分隔符。
RewriteCond
将TestString
%{ENV:SUBPATH}::%{REQUEST_URI}
扩展为以下内容:

misc/subdir/file.xyz::/path_to/current_folder/misc/subdir/file.xyz

然后我们的CondPattern
^(.*):(.*)\1$

  • ^(.*):
    匹配
    misc/subdir/file.xyz::
  • \1
    是第一个捕获组,
    misc/subdir/file.xyz
  • (*?)\1$
    变为
    (*?)misc/subdir/file.xyz$
  • 因此,我们的第二个捕获组
    (.*)
    匹配剩余的
    /path\u到/current\u文件夹/

  • 我们的
    RewriteRule
    CWD
    设置为
    %2
    ,这是CondPattern的第二个捕获组。

    如果您在htaccess中有
    RewriteBase
    命令,您可以对此进行注释,然后它将自动解析到该目录。

    这是相对于文档根目录的?请参阅update@sumurai8是否可以更改这两个命令,以便它们匹配包含多个正向斜杠的URL?例如,这将不起作用:/directory/a///b/c/(注意a后的3个斜杠)是的,使用重定向规则,所有多个斜杠应首先修剪为单个的
    ///code>。今天,五年多之后,您可能已经保存了我的理智。非常感谢。这开始吞噬我的灵魂!老兄,你救了我的命,这个100%有效,而且它不像鞋面那么短。如果可以的话,我已经将链接改为使用archive.org。对于未来的验证: