首先我要说的是,我对 .htaccess 编写还很陌生,通常把细节留给我的托管服务提供商。我最近决定在 php 中实现一个手动 MVC 框架,并使用 .htaccess 文件使用“seo”友好 URL 进行重定向。我的 MVC 实现使用变量模块、类、事件和参数。它们按该顺序在 URL 中指定,例如http://mydomain.com/module/class/event/parameter。我希望它能在您删除 URL 的任何部分时正常工作。这一切都运行正常,直到我将我的网站上移一级并随后复制了我的 .htaccess 文件。现在我得到了一个无限重定向循环,其中一条规则在我移动之前运行正常。
这是我的.htaccess 文件:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^$ /index.php?module=default&class=home [QSA,L]
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^([^/]*)$ /index.php?module=$1 [QSA,L]
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^([^/]*)/([^/]*)/([^/]*)$ \
/index.php?module=$1&class=$2&event=$3 [QSA,L]
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)$ \
/index.php?module=$1&class=$2&event=$3¶meter=$4 [QSA,L]
现在,如果我删除以下部分:
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^([^/]*)$ /index.php?module=$1 [QSA,L]
效果很好。问题是如果我忽略了这一点,然后有人输入http://mydomain.com/module我得到了 404(因为该目录不存在,并且没有匹配的规则)。那么为什么该规则现在不起作用,为什么当 index.php(和此 .htaccess 文件)位于子目录中时它会起作用?
答案1
嗯,看起来 php 路由器解决方案是最好的。
这是我现在使用的简化版 .htaccess
RewriteEngine On
# Disable rewriting for existing files or directories
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# redirect all other requests to index.php
RewriteRule ^.*$ index.php [PT,L]
RewriteRule ^$ index.php [PT,L]
这行“神奇”的代码完成了 .htaccess 之前所做的所有繁重工作:
$url = explode('/', trim($_SERVER['REQUEST_URI'], '/'));
现在我可以从 $url 数组中分配模块、类、事件和参数值。它还解决了我可能需要为事件添加多个参数的问题。我不想必须为每个级别不断向 .htaccess 文件添加规则。现在我可以提供任意数量的参数并在代码中处理路由逻辑。