.htaccess 使用htaccess重定向全部到index.php

yptwkmov  于 2023-01-31  发布在  PHP
关注(0)|答案(8)|浏览(196)

我正在写一个简单的基于PHP的MVC框架。我希望这个框架能够安装在任何目录。
我的PHP脚本获取请求URI并将其分解为多个段,它将段1作为控制器,将段2作为操作,这样做就可以了:

http://www.example.com/mvc/module/test/

它将转到特定的模块控制器和方法。现在我有一个默认的控制器,家庭控制器,它在文件夹家庭。
现在,当我直接访问此文件夹http://www.example.com/mvc/home/时,它将显示403 forbidden,因为此文件夹确实存在,相反,它也应该返回到http://www.example.com/mvc/index.php
如果我将框架安装在一个不同的文件夹中,比如说文件夹framework,它必须重定向回http://www.example.com/framework/index.php
我想将每个文件夹和php文件重定向回index.php,让其他一切保持原样。
我遇到的第一个问题是它从来不会重定向到正确的文件夹,总是重定向到域根文件夹。
我是这么试的:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
2nbm6dog

2nbm6dog1#

您的重写规则看起来基本正常。
首先确保.htaccess文件在文档根目录中(与index.php相同的位置),否则它只会影响它所在的子文件夹(以及其中的任何子文件夹-递归)。
接下来,对规则进行细微更改,使其类似于:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]

目前,您只是在.上进行匹配,.是任何字符的一个示例,您至少需要.*来匹配任何字符的任何数量的示例。
$_GET['path']变量将包含伪目录结构,例如/mvc/module/test,然后您可以在index.php中使用它来确定 Controller 和您想要执行的操作。
如果你想把整个shebang安装在一个子目录中,比如/mvc//framework/,最简单的方法是稍微修改重写规则来考虑这个问题。

RewriteRule ^(.*)$ /mvc/index.php?path=$1 [NC,L,QSA]

并确保您的index.php位于该文件夹中,而.htaccess文件位于文档根目录中。

$_GET['path']的替代方案(于2018年2月和2019年1月更新)

path 设置为$_GET变量实际上是没有必要的(现在甚至也不常见),许多框架将依赖$_SERVER['REQUEST_URI']来检索相同的信息-通常是为了确定使用哪个 Controller-但原理完全相同。
这确实稍微简化了RewriteRule,因为您不需要创建 path 参数(这意味着OP的原始RewriteRule工作):

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [L,QSA]

但是,有关在子目录中安装的规则仍然适用,例如

RewriteRule ^.*$ /mvc/index.php [L,QSA]

旗帜:

NC = No Case(不区分大小写,由于模式中没有字符,因此实际上不需要)
L =最后一个(在此重写之后,它将停止重写,因此请确保它是重写列表中的最后一个)
QSA = Query String Append,以防你在末尾有类似?like=penguins的东西,你想保留并传递给index.php。

yv5phkfx

yv5phkfx2#

要将不存在的所有内容重定向到index.php,还可以使用**FallBackResource**指令

FallbackResource /index.php

它的工作原理与ErrorDocument相同,当您请求服务器上不存在的路径或文件时,该指令会静默地将请求转发到index.php
如果要将所有内容(including existant files or folders)重定向到index.php,可以使用如下代码:

RewriteEngine on

RewriteRule ^((?!index\.php).+)$ /index.php [L]

注意,模式^((?!index\.php).+)$匹配除index.php之外的任何uri,我们排除了目标路径以防止无限循环错误。

0s7z1bwu

0s7z1bwu3#

对于这个 * 问题 *,有一个"窍门"适合所有场景,一个如此明显的解决方案,你将不得不尝试它才能相信它实际上是有效的...:)
在这里...

<IfModule mod_rewrite.c>

   RewriteEngine On

   RewriteCond %{REQUEST_FILENAME}  -f [OR]
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteRule ^(.*)$ index.php [L,QSA]

</IfModule>

基本上,您是在请求MOD_REWRITE将URI请求转发到index.php总是在文件存在时以及总是在请求的文件不存在时!
在研究MOD-REWRITE的源代码以了解它的工作原理时,我意识到它的所有检查总是在验证引用的文件是否存在之后进行的。只有这样,RegEx才被处理。即使当你的URI指向一个文件夹,Apache也会强制检查其配置文件中列出的 * 索引文件 *。
基于这个简单的发现,显而易见,只要我们双击文件存在检查并将两个结果路由到同一个端点,覆盖100%的可能性,一个简单的文件验证就足以所有可能的调用

    • 重要提示:请注意index.php中没有"/**"。默认情况下,MOD_REWRITE将使用设置为"基本文件夹"的文件夹进行转发。其优点在于它不一定是站点的"根文件夹",因此此解决方案适用于localhost/和/或您应用它的任何子文件夹。

最后,我之前测试过的一些其他解决方案(看起来运行良好的那些)破坏了PHP通过相对路径"请求"文件的能力,这是一个令人沮丧的问题。
有些人可能会说这是一个不优雅的解决方案,实际上可能是这样,但就测试而言,在几个场景、几个服务器、几个不同的Apache版本等情况下,这个解决方案在所有情况下都100%有效!

bvk5enib

bvk5enib4#

您可以使用类似于以下内容的内容:

RewriteEngine on
RewriteRule ^.+$ /index.php [L]

这会将每个查询重定向到根目录的index.php。注意,它还会重定向对现有文件的查询,如图像、javascript文件或样式表。

zfycwa2u

zfycwa2u5#

愚蠢的答案,但如果你不知道为什么它不重定向检查,以下是为网络文件夹启用。
AllowOverride All
这将使您能够运行必须运行的htaccess!(有替代方案,但没有将导致问题https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride)

wmomyfyw

wmomyfyw6#

如果目录存在(对于核心框架文件夹和文件),您可能还想知道如何将所有请求重定向到框架索引处理程序,在一些错误/成功尝试之后,我注意到我只需要更改.htaccess文件中的RewriteCond

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

上面的条件声明“未找到文件”和“未找到目录”,好吧,如果只是删除“未找到”(!-d)行,并以类似下面的内容结束呢:

RewriteEngine on
RewriteBase /framework/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /framework/index.php [L,QSA]

它对我来说就像一种魔力

czfnxgou

czfnxgou7#

我在Laravel 7项目中遇到了同样的问题,在Debian 10的共享主机中,我必须在/public/目录中添加RewriteBase /到我的.htaccess中,所以.htaccess看起来像

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [L,QSA]
n6lpvg4x

n6lpvg4x8#

完成此操作后,不要忘记在<a href="{the chosen redirected name}"> home</a>中更改您的href
示例:
.htaccess文件

RewriteEngine On

RewriteRule ^about/$ /about.php

PHP文件:

<a href="about/"> about</a>

相关问题