Regex 将RewriteBase动态设置为当前文件夹路径
有没有办法将RewriteBase设置为相对于主机根目录的当前文件夹(即.htaccess文件所在的文件夹)的路径 我有一个CMS,如果我将它移动到主机中的目录,它将不起作用,除非我将RewriteBase设置为相对于主机根目录的目录路径。我希望我的CMS只使用复制和粘贴,而不更改htaccess中的任何代码 更新: 例如: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/ 如果我
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
等,但RHS端,即条件字符串不能使用这些%2
,$1
或$2
,%1
变量%2
- 在RHS条件部分内,我们可以使用的唯一反向参考是内部反向参考,即我们在该条件本身中捕获的组。它们由
、\1
等表示\2
- 在
中,第一个捕获的组是RewriteCond
。它将由内部反向参考(.*?/)
表示\1
- 通过比较
和%{REQUEST\u URI}
,可以看出此规则基本上是动态查找$1
。RewriteBase
的示例将是%{REQUEST_URI}
,相同示例URI的/directory/foobar.php
示例将是$1
<代码>^(.*?/)(.*):\2$正在将差异放入第一个捕获的组foobar.php
或%1
。对于我们的示例,它将使用值\1
填充/directory/
和%1
,该值稍后在\1
中设置env变量E=BASE:%1
时使用%{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。对于未来的验证: