使用 htaccess 将所有内容重定向到 index.php
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18406156/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Redirect all to index.php using htaccess
提问by David Ericsson
I'm writing a simple PHP-based MVC-ish framework. I want this framework to be able to be installed in any directory.
我正在编写一个简单的基于 PHP 的 MVC-ish 框架。我希望这个框架能够安装在任何目录中。
My PHP script grabs the request uri and breaks it off into segments. It makes segment 1 the controller and segment 2 the action. This goes all fine when I do this:
我的 PHP 脚本获取请求 uri 并将其分解为多个段。它使段 1 成为控制器,段 2 成为动作。当我这样做时,一切都很好:
http://www.example.com/mvc/module/test/
http://www.example.com/mvc/module/test/
It will go to the specific module controller and method. Now I have a default controller, the home controller, which is in folder home.
它将转到特定的模块控制器和方法。现在我有一个默认控制器,home 控制器,它在文件夹 home 中。
Now when I access this folder directly http://www.example.com/mvc/home/It will display a 403 forbidden, because this folder does exist, instead it should also go back to http://www.example.com/mvc/index.php
现在当我直接访问这个文件夹 http://www.example.com/mvc/home/它会显示一个 403 forbidden,因为这个文件夹确实存在,它也应该回到 http://www.example.com /MVC/index.php
If I would have installed the framework in a different folder, lets say folder framework it has to redirect back to http://www.example.com/framework/index.php
如果我将框架安装在不同的文件夹中,假设文件夹框架必须重定向回http://www.example.com/framework/index.php
I would like to redirect every folder and php file back to the index.php, leaving everything else the way it is.
我想将每个文件夹和 php 文件重定向回 index.php,让其他一切保持原样。
My first problem I encountered was it never redirects to the right folder, always to the domain root folder.
我遇到的第一个问题是它永远不会重定向到正确的文件夹,总是重定向到域根文件夹。
This is what I tried :
这是我试过的:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
回答by CD001
Your rewrite rule looks almost ok.
你的重写规则看起来几乎没问题。
First make sure that your .htaccess
file is in your document root (the same place as index.php
) or it'll only affect the sub-folder it's in (and any sub-folders within that - recursively).
首先确保您的.htaccess
文件在您的文档根目录中(与 相同的位置index.php
),否则它只会影响它所在的子文件夹(以及其中的任何子文件夹 - 递归)。
Next make a slight change to your rule so it looks something like:
接下来对您的规则稍作更改,使其看起来像:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path= [NC,L,QSA]
At the moment you're just matching on .
which is oneinstance of any character, you need at least .*
to match any number of instances of any character.
在你刚匹配的那一刻.
这是一个任意字符的情况下,你至少需要.*
匹配任意数量的任何字符的实例。
The $_GET['path']
variable will contain the fake directory structure, so /mvc/module/test
for instance, which you can then use in index.php to determine the Controllerand actions you want to perform.
该$_GET['path']
变量将包含伪造的目录结构,/mvc/module/test
例如,您可以在 index.php 中使用它来确定您想要执行的控制器和操作。
If you want the whole shebang installed in a sub-directory, such as /mvc/
or /framework/
the least complicated way to do it is to change the rewrite rule slightly to take that into account.
如果您希望将整个 shebang 安装在子目录中,例如/mvc/
或/framework/
最简单的方法是稍微更改重写规则以将其考虑在内。
RewriteRule ^(.*)$ /mvc/index.php?path= [NC,L,QSA]
And ensure that your index.php
is in that folder whilst the .htaccess
file is in the document root.
并确保您index.php
在该文件夹中,而.htaccess
文件在文档根目录中。
Alternative to $_GET['path']
(updated Feb '18 and Jan '19)
替代$_GET['path']
(更新于 2018 年 2 月和 19 年 1 月)
It's not actually necessary (nor even common now) to set the pathas a $_GET
variable, many frameworks will rely on $_SERVER['REQUEST_URI']
to retrieve the same information - normally to determine which Controllerto use - but the principle is exactly the same.
将路径设置为$_GET
变量实际上并不是必需的(现在甚至不常见),许多框架将依赖于$_SERVER['REQUEST_URI']
检索相同的信息 - 通常确定使用哪个控制器- 但原理完全相同。
This does simplify the RewriteRule
slightly as you don't need to create the pathparameter (which means the OP's original RewriteRule
willnow work):
这并简化RewriteRule
略有你不需要创建路径参数(这意味着OP的原始RewriteRule
将现在的工作):
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [L,QSA]
However, the rule about installing in a sub-directory still applies, e.g.
但是,关于在子目录中安装的规则仍然适用,例如
RewriteRule ^.*$ /mvc/index.php [L,QSA]
The flags:
旗帜:
NC
= No Case (not case sensitive, not really necessary since there are no characters in the pattern)
NC
= 不区分大小写(不区分大小写,实际上没有必要,因为模式中没有字符)
L
= Last (it'll stop rewriting at after this Rewrite so make sure it's the last thing in your list of rewrites)
L
= 最后(它会在此重写之后停止重写,因此请确保它是重写列表中的最后一件事)
QSA
= Query String Append, just in case you've got something like ?like=penguins
on the end which you want to keep and pass to index.php.
QSA
= Query String Append,以防万一?like=penguins
你想保留并传递给index.php。
回答by starkeen
To redirect everything that doesnt exist to index.php
, you can also use the FallBackResource
directive
要将不存在的所有内容重定向到index.php
,您还可以使用FallBackResource
指令
FallbackResource /index.php
It works same as the ErrorDocument
, when you request a non-existent path or file on the server, the directive silently forwords the request to index.php
.
它的工作原理与 相同ErrorDocument
,当您请求服务器上不存在的路径或文件时,该指令将请求以静默方式转发给index.php
。
If you want to redirect everything (including existant files or folders
) to index.php
, you can use something like the following :
如果您想将所有内容 ( including existant files or folders
)重定向到index.php
,您可以使用以下内容:
RewriteEngine on
RewriteRule ^((?!index\.php).+)$ /index.php [L]
Note the pattern ^((?!index\.php).+)$
matches any uri except index.php
we have excluded the destination path to prevent infinite looping error.
请注意,该模式^((?!index\.php).+)$
匹配任何 uri,除非index.php
我们排除了目标路径以防止无限循环错误。
回答by Technoh
You can use something like this:
你可以使用这样的东西:
RewriteEngine on
RewriteRule ^.+$ /index.php [L]
This will redirect every query to the root directory's index.php. Note that it will also redirect queries for files that exist, such as images, javascript files or style sheets.
这会将每个查询重定向到根目录的 index.php。请注意,它还会重定向对现有文件的查询,例如图像、javascript 文件或样式表。
回答by Julio Marchi
There is one "trick" for this problemthat fits all scenarios, a so obvious solution that you will have to try it to believe it actually works... :)
这个问题有一个适合所有场景的“技巧” ,一个如此明显的解决方案,你必须尝试相信它真的有效...... :)
Here it is...
这里是...
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L,QSA]
</IfModule>
Basically, you are asking MOD_REWRITEto forward to index.php
the URI request always when a file existsAND always when the requested file doesn't exist!
基本上,您要求MOD_REWRITE始终在文件存在时转发到index.php
URI 请求,并且始终在请求的文件不存在时转发!
When investigating the source code of MOD-REWRITEto understand how it works I realized that all its checks always happen after the verification if the referenced file exists or not. Only then the RegEx
are processed. Even when your URI points to a folder, Apache will enforce the check for the index fileslisted in its configuration file.
在调查MOD-REWRITE的源代码以了解它的工作原理时,我意识到它的所有检查总是在验证引用文件是否存在之后进行。只有这样RegEx
处理。即使您的 URI 指向一个文件夹,Apache 也会强制检查其配置文件中列出的索引文件。
Based on that simple discovery, turned obvious a simple file validation would be enough for all possible calls, as far as we double-tap the file presence check and route both results to the same end-point, covering 100% of the possibilities.
基于这个简单的发现,显然一个简单的文件验证就足以满足所有可能的调用,只要我们双击文件存在检查并将两个结果路由到同一个端点,覆盖 100% 的可能性。
IMPORTANT:Notice there is no "/" in index.php
. By default, MOD_REWRITEwill use the folder it is set as "base folder" for the forwarding. The beauty of it is that it doesn't necessarily need to be the "root folder" of the site, allowing this solution work for localhost/
and/or any subfolder you apply it.
重要提示:请注意,没有“ /中” index.php
。默认情况下,MOD_REWRITE将使用它设置为“基本文件夹”的文件夹进行转发。它的美妙之处在于它不一定需要是站点的“根文件夹”,允许此解决方案适用于localhost/
和/或您应用它的任何子文件夹。
Ultimately, some other solutions I tested before (the ones that appeared to be working fine) broke the PHP ability to "require" a file via its relative path, which is a bummer. Be careful.
最终,我之前测试过的一些其他解决方案(那些看起来运行良好的解决方案)破坏了 PHP 通过其相对路径“要求”文件的能力,这很糟糕。当心。
Some people may say this is an inelegant solution. It may be, actually, but as far as tests, in several scenarios, several servers, several different Apache versions, etc., this solution worked 100% on all cases!
有些人可能会说这是一个不雅的解决方案。实际上可能是这样,但就测试而言,在多个场景、多个服务器、多个不同的 Apache 版本等中,该解决方案在所有情况下均 100% 有效!
回答by Antony
Silly answer but if you can't figure out why its not redirecting check that the following is enabled for the web folder ..
愚蠢的回答,但如果您不知道为什么它不重定向,请检查是否为 web 文件夹启用了以下内容..
AllowOverride All
AllowOverride All
This will enable you to run htaccess which must be running! (there are alternatives but not on will cause problems https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride)
这将使您能够运行必须正在运行的 htaccess!(有替代方案但不开启会导致问题https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride)
回答by Collins Benson
After doing the don't forget to change your anchor tag, home
完成后不要忘记更改您的锚标签,回家
Example:
例子:
.htacces file
RewriteEngine On
RewriteRule ^about/$ /about.php
PHP file:
<a href="about/"> about</a>
回答by AugustoM
just in case you were still wondering how to redirect all request either if the directory exists (for core framework folders and files) to the framework index handler, after some error/success attempts just noticed I just needed to change the RewriteCond in the .htaccess file
以防万一您仍然想知道如果目录存在(对于核心框架文件夹和文件)到框架索引处理程序,如何将所有请求重定向到框架索引处理程序,在一些错误/成功尝试之后才注意到我只需要更改 .htaccess 中的 RewriteCond文件
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
the above condition states "not found files" and "not found directories", ok, what if just remove "not found" (!-d) line, and ended with something like the below:
上面的条件说明“未找到文件”和“未找到目录”,好吧,如果只是删除“未找到”(!-d)行,并以如下内容结束会怎样:
RewriteEngine on
RewriteBase /framework/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /framework/index.php [L,QSA]
It worked for me like a charm
它像魅力一样对我有用