几乎在我工作的任何项目中,都会出现.htaccess的一些问题。我通常只找到最简单的解决方案,因为我对Apache,服务器等没有任何了解或理解。但这次我想我会问你们。
这是我(简化)设置中的文件和文件夹:
/modrewrite-test
.htaccess
/config
/inc
/lib
/public_html
.htaccess
/cms
/navigation
index.php
edit.php
/pages
index.php
edit.php
login.php
page.php
“config”,“inc”和“lib”文件夹意味着从网站的根目录“隐藏”。我尝试通过在根目录中创建一个将用户重定向到“public_html”的.htaccess文件来实现此目的。 .htacess文件包含:
RewriteEngine On
RewriteRule (.*) public_html/$1
这很完美。如果我在浏览器中输入“http://localhost/modrewrite-test/login.php”,我最终会出现在public_html / login.php中,这是我的意图。所以这很好。 “public_html”中的.htaccess文件包含:
RewriteEngine On
# Root
RewriteRule ^$ page.php [L]
# Login
RewriteRule ^(admin)|(login)\/?$ login.php [L]
# Page (if not a file/directory)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ page.php?url=$1 [L]
如果我尝试触及“http://localhost/modrewrite-test/”,第一次重写只会将我重定向到public_html / page.php。下一次重写只是为了方便用户尝试登录 - 所以如果他们尝试访问“http://localhost/modrewrite-test/admin”或“http://localhost/modrewrite-test/login”,他们最终会登录login.php文件。第三次和最后一次重写处理其余请求。如果我尝试达到“http://localhost/modrewrite-test/bla/bla/bla”,它只会将我重定向到public_html / page.php(使用'url'GET-variable set),而不是找到一个名为“la”的文件夹,其中包含一个名为“bla”的文件夹“等等。
所有这些工作都很完美,但是当我尝试在URL的末尾没有斜杠时达到“http://localhost/modrewrite-test/cms/navigation”时会出现一些小问题。当我尝试访问该页面时,浏览器会以某种方式重定向到“http://localhost/modrewrite-test/public_html/cms/navigation/”。显示正确的页面,但为什么会重定向并在URL中添加“public_html”部分?所需的行为是URL保持不变,并显示页面public_html / cms / navigation / index.php。
找到(简化)中的文件和文件夹答案 0 :(得分:3)
在尝试访问现有目录而没有斜线时,我遇到了与“奇怪”重定向相同的问题。在我的例子中,这个重定向是由 mod_dir Apache模块完成的。要禁用重定向,我使用了DirectorySlash指令。尝试在字符串后面输入 .htaccess 文件:
DirectorySlash Off
答案 1 :(得分:0)
RewriteBase可能有所帮助。在public_html / .htaccess中试试这个:
RewriteEngine On
RewriteBase /
答案 2 :(得分:0)
将以下内容添加到 /modrewrite-test/.htaccess
:
RewriteBase /modrewrite-test
为了安全起见,我还要向 /modrewrite-test/public_html/.htaccess
添加相同的规则。我发现总是设置RewriteBase可以防止将来出现很多潜在的问题。但是,这意味着如果更改站点的URI结构,则可能需要更新值。
<强> 更新 强>
我不认为这对您当前的文件夹结构是可行的。我认为问题是现有的子目录阻止重写规则被触发。请注意这种行为 - 由于这两个条件,在您处理不存在的文件和目录时一切正常:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
但是,如果您尝试从现有子目录中打开任何索引文件,则会被重定向到.../public_html/...
。由于您可以正确地打开/modrewrite-test/cms/navigation/edit.php
,我只能假设某个Apache核心指令覆盖了该请求,该指令在文件夹URL的末尾添加了斜杠。请注意,如果每个URL都有一个结尾斜杠,一切正常(即Apache核心目录不需要“更正”您的URL,因此所有内容都会被您自己的重写规则重写)。
建议的解决方案(除非有人能提出更好的建议):
按如下方式更改/modrewrite-test/public_html/.htaccess
:
RewriteEngine On
RewriteBase /modrewrite-test
# Page (if not a file/directory)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ page.php?url=$1 [L]
然后从子文件夹中删除所有PHP文件并使用Front Controller pattern,即通过主page.php
文件路由所有请求,并且不要在下面委派任何内容。
然后,您可以使用Factory pattern根据$ _GET ['url']的内容直接从主navigation/edit.php
文件启动单个UI(即page.php
)(确保正确消毒)。
更新#2:
这个other post on StackOverflow建议Zend框架使用的项目结构 - 它基本上显示了我上面提出的方法。无论您是否使用Zend Framework,它都是有价值的信息资产。