将所有请求转发到一个index.php文件,用于非现有文件,但*包括* index.php本身

时间:2018-05-31 18:51:23

标签: apache .htaccess

所以我在.htaccess文件中有这个非常典型的“单点入口”配置:

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

它工作正常。现在 - 我也对index.php文件本身的请求有什么行为。所以我这样做:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
#file must not exist:
RewriteCond %{REQUEST_FILENAME} !-f [or]

# *unless* this is the index.php *itself*, then I also 
#want to pass it to itself. 
RewriteCond %{REQUEST_FILENAME} index.php

RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]

所以我们在这里有一些例外 - 当文件不存在时继续,但是当它存在但是它是'index.php'时。

它有效,但不幸的是它也适用于结构更深层的文件。我想要的只是捕获'index.php'与.htaccess本身处于同一级别。

更新 也许我应该澄清一下。我想为php创建一个非常通用的,开箱即用的单一入口点,如下所示:

https://github.com/kpion/point1

它“有效”,但我觉得我应该这样做有点不同。我已经问了一个类似的问题(The utlimate way to make a single entry point (front controller) working with the most common web server setups),但被认为“太长了”,所以这是我的第二种方法:)

请记住,我不能在条件中使用^ / index.php - 因为'请求uri并不真的需要从它开始。这个htaccess也可以更深,即文档根目录更深。这实际上很常见,当我在/ var / www / html中有很多小项目时,我不想为所有东西创建一个vhost。所以“root”是/ var / www / html,现在是:

示例:

该项目位于 的/ var / www / html等/点/点1

.htaccess在里面。它将对不存在的文件的所有请求转发到index.php。除了我的一些额外的行,它还将自己转发到index.php。

注意:%{REQUEST_URI}在这种情况下,当我们打开/ var / www / html / point / point1等于“/point/point1/index.php”时

/index.php

当我调用http://localhost/point/point1/.local/noExistinFilehttp://localhost:82/point/point1/时,它会正常工作(这将指向index.php,它将与我上一次的RewriteCond匹配)。

但是,当我在/var/www/html/point/point1/.local/index.php中有一个文件时,我打电话给http://localhost2/point/point1/.local/index.php - 我想要这是为了传递条件,我不希望它被转发到index.php。

所以我需要相对到.htaccess位置。

2 个答案:

答案 0 :(得分:2)

这应该有效:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
#file must not exist:
RewriteCond %{REQUEST_FILENAME} !-f [or]
#or is /index.php
RewriteCond %{REQUEST_URI} ^/index.php$
RewriteRule ^(.*)$ index.php?url=$1 [NC,L,QSA]

答案 1 :(得分:0)

啊,我忘了我问过这个问题。对于任何感兴趣的人:我发现解决方案非常简单:

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

# lets forward the index.php itself as well, to be later consistent in how we handle things:
RewriteRule ^(index.php)$ index.php?url=index.php [QSA,L]

最后一行完成了这项工作,因为:

  1. 上面的RewriteCond显然不适用(默认情况下它们仅适用于下面的“RewriteRule”)。所以-f(必须不存在)不适用,这很酷。

  2. 现在关键部分:RewriteRule 中的测试字符串 文件/目录相对到目录.htaccess是因此,如果.htaccess文件位于/ var / www / html / point / point1内,我们要求:

    http://whateverHostWeSetPointingToThisDir/index.php然后在RewriteRule中测试的字符串正好是“index.php”。当我们要求时

    http://localhost/point/point1/blah/index.php然后,假设... point1指向我们的'point1'目录,测试的是“blah / index.php”。

  3. 这就是为什么RewriteRule ^(index.php)$匹配与.htaccess本身在同一目录中的'index.php'文件。无论主机名,父目录名称还是其他任何名称。

    顺便说一句:如果我们请求http://whateverHostWeSetPointingToThisDir,那么如果我们设置了DirectoryIndex index.php,那么这也会有效,但这并不是真正相关的。