我Walf在搬运路线通过路由器类同意是一个更好的主意(尤其是从长远来看!)比使用.htaccess
重定向。
但是,由于您的问题似乎更多的是为什么这不工作,而不是你应该怎么做,这里是一个解释发生了什么。
我将使用这些URL作为例子:
localhost:8080
localhost:8080/app
localhost:8080/app/customers/id/5
你的第一条规则:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTP_HOST} ^(www.)?localhost:8080$
RewriteRule ^(.*)$ /views/$1
如你意,这个重写规则将匹配这不是一个文件,而不是目录中的任何URL ,并制作到localhost:8080。
localhost:8080 # not matched because it leads to a directory.
localhost:8080/app -> localhost:8080/views/app
localhost:8080/app/customers/id/5 -> localhost:8080/views/app/customers/id/5
你的下一个规则:
RewriteRule ^(/)?$ /views/index.php [L]
重要的是要认识到的RewriteCond陈述仅适用于第一重写规则跟了上去,因此正被这里检查了所有的路径是非常重要的。
备注:^(/)?$
,因为您未使用$1
,可简化为^/?$
。
localhost:8080 -> localhost:8080/views/index.php
localhost:8080/views/app # not matched
localhost:8080/views/app/customers/id/5 # not matched
符合规定L
标志,Apache将立即停止当前迭代,并开始从顶部再次匹配。 The documentation is badly worded。因此,localhost:8080/views/index.php
将通过第一条规则运行,不匹配,通过此规则运行,无法匹配,然后由于没有其他规则存在检查(但)不会进行重写。
现在让我们来看看添加破损规则时会发生什么。
RewriteRule /id/(.*) customers.php?id=$1
这里有几个问题。首先,由于您不需要网址以/id/
开头,即使您已经重写了网址,该规则也会始终与包含/id/
的网址匹配。如果您使用^/id/(.*)
对此进行了修改,那么您仍然会遇到问题,因为重写RegEx所测试的字符串已删除了前导斜杠。最后也是最重要的是,customers.php
不存在于您的根目录中。
localhost:8080/views/index.php # not matched
localhost:8080/views/app # not matched
localhost:8080/views/app/customers/id/5 -> localhost:8080/customers.php?id=5
这是当前文件中的最后一条规则,所以现在Apache将重新开始。 customers.php
不存在于您的目录中,因此它将被重写为views/customers.php
。没有其他规则匹配,但URL已更改,所以Apache将重新开始,因为/views/customers.php
不存在,它将被重写为/views/views/customers.php
......此模式将重复,直到达到最大迭代限制并且Apache响应500错误。
您可以通过以下几种方法解决。这将是我的首选方法,但只有当你不能使用路由器。
RewriteEngine on
# Rewrite the main page, even though it is a directory
RewriteRule ^/?$ views/index.php [END]
# Don't rewrite any existing files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .? - [S=999,END]
RewriteRule ^app/?$ views/app/index.php [END]
RewriteRule ^app/id/(.*)$ views/app/customers.php?id=$1 [END]
TL; DR使用基于PHP的路由器。 .htaccess
规则可能令人难以置信地混淆。
/id/(.*)将始终与customers/php?** id **匹配,因此您的规则将始终循环 – Gerrit0
,那么如何更改该行可以在我的情况下工作? –
对不起,我对这个假设过于仓促,问题不在于这个问题,问题在于你的第一条规则,它总是匹配的,所以总是在你的URL的开头添加/查看/。 htaccess规则非常容易搞乱。在尝试很好地回答这个问题之前,我需要学习更多。 – Gerrit0