如何处理Front Controller模式中的子目录

时间:2015-01-26 22:33:30

标签: .htaccess mod-rewrite url-rewriting front-controller

TL; DR :如果请求没有文件的子目录,我的URL重写会中断。我没有按预期加载默认home页面,而是收到了 403 Forbidden 错误。

我使用Apache URL重写来使用Front Controller模式构建网站。到目前为止,我的.htaccess看起来像这样:

Options -Indexes
RewriteCond %{REQUEST_URI} ^/(subdir|subdir/.*|subdir2|subdir2/.*).*$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+) index.php?request=$1 [QSA]

所以这适用于除子目录请求之外的所有请求:

  • mydomain.com/会导致 - >

    • mydomain.com/index.php home.inc内容
  • mydomain.com/page1会导致 - >

    • mydomain.com/index.php /pages/page1.inc内容
  • mydomain.com/subdir/会导致 - >

    • 403 Forbidden
  • mydomain.com/subdir/page1会导致 - >

    • mydomain.com/index.php /subdir/pages/page1.inc内容

下面的详细信息可能并不重要,因为问题可能发生在.htaccess


index.php中,我正在捕获请求并使用它来从目录/pages中获取相应的包含页面,该目录包含具有每个页面内容的文件。这是index.php的代码(稍微简化):

//grab the actual HTTP request
$request = $_GET['request'];

//if the request has slashes, isolate the directory part into $dir
$slashPos = strrpos($request, "/");
if($slashPos !== false){
    $dir = substr($request, 0, $slashPos) . "/";
    $page = basename($request, ".inc");
} else {
    $dir = "";
    $page = request;
}

//use "home" if no filename is specified.
if($page==""){$page="home";}

//build path to content include
$content = $dir . "pages/" . $page . ".inc";

//output page
require("header.php"); 
require($content ); 
require("footer.php");

这适用于根目录。对mydomain.com/page1的请求会导致mydomain.com/index.php的内容包含mydomain.com/pages/page1

它也适用于子目录中的 pages mydomain.com/subdir/page1请求导致mydomain.com/index.php被提供,其中包含mydomain.com/subdir/pages/page1的内容。功能

当请求是针对实际目录时,它都会中断。因此mydomain.com/subdir/会返回 403 Forbidden 。它为什么这样做?我希望它$dirsubdir$page home加载{我设置为$page==""时的默认值。

是的,Options -Indexes可能导致403,但为什么只在子目录上?它根本没有403RewriteCond %{REQUEST_URI} ^/(subdir|subdir/.*|subdir2|subdir2/.*).*$中的.htaccess行应该抓住它,对吗?

1 个答案:

答案 0 :(得分:0)

好的,我明白了。问题是subdir实际上不在网络根目录。我的整个网站实际上都在自己的子目录中工作。换句话说,我没有在

工作
mydomain.com/

作为根,我在

工作
mydomain.com/mydivision/

作为根。显然在这一行:

RewriteCond %{REQUEST_URI} ^/(subdir|subdir/.*|subdir2|subdir2/.*).*$

^让它在实际的webroot中寻找subdir。要解决此问题,我已移除^或在^之后将我的实际子域名添加到该行。