用于从父目录

时间:2017-10-19 22:33:02

标签: php apache .htaccess mod-rewrite url-rewriting

我正在寻找将映射以下内容的.htaccess重写规则

GET /a/       => a/index.php
GET /a/b/     => a/b/index.php
GET /a/b/c/   => a/b/index.php

基本上,如果目录中存在index.php文件,则应该提供该文件。如果没有,那么它应该在index.php的父目录中查找并提供。

我试图在PHP中获取干净的URL,而不必通过单个index.php文件路由所有内容。

3 个答案:

答案 0 :(得分:1)

第一个解决方案假设请求映射到物理目录路径,例如。 a中的bc/a/b/c/RewriteRule形式的请求中都是文件系统上的所有目录...

您不需要为此使用mod_rewrite(即DirectoryIndex)。您只需指定相对/a/b/c/文档即可。例如,要处理4级深度的目录结构(即。DirectoryIndex index.php ../index.php ../../index.php ../../../index.php ):

index.php

如果没有找到目录索引文档,那么你将获得通常的403 Forbidden(假设目录索引被禁用)。

如果您沿文件系统路径删除了所有/a/b/c/个文档,那么如果它尝试获取文档根目录上方的索引文档,则会收到400个错误请求。

UPDATE:但是,实际上需要的是多级前端控制器类型模式,因为请求的URL不一定作为物理文件系统路径存在。例如,给定a形式的URL,可能只有bc/是物理目录而/a/b/index.php只是一个额外的URL路径,应该是传递到位于/a/index.php/index.php或甚至RewriteEngine On # Exception - Reached the document root then stop # (Prevents rewrite loop if index.php is missing - 404 instead) RewriteRule ^index\.php$ - [L] # Exception - Any request for a valid file stop here RewriteCond %{REQUEST_FILENAME} -f RewriteRule ^ - [L] # If already requesting "index.php" then step up a directory RewriteRule ^(.*/)?[^/]+/index\.php$ /$1index.php [L] # Otherwise try "index.php" in the current path segment RewriteRule ^(.*/)?[^/]*$ /$1index.php [L] 的前端控制器,具体取决于首先找到的位置。

对于通用的任何目录级深层目录结构,您可以执行以下操作:

(.*/)?

正则表达式开头的可选/a/index.php模式是允许一直钻到文档根目录。如果这不是可选的(并且在捕获的模式中包含斜杠),那么它将在文档根目录中停止一个目录(即在{{1}})。

通过不专门检查请求是否映射到目录,它可以在父目录中调用前端控制器,当它从所请求的目录中丢失时。

答案 1 :(得分:1)

经过一些修修补补后,我找到了一个似乎有效的解决方案。我基本上捕获已知路径段并使用捕获变量映射到相对于文档根目录的文件系统。然而,理想的是有一个N级深度的正则表达式需要多个重写规则。

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
# 3 levels deep
# GET /a/b/c-some-thing-here    
RewriteRule (.*)/(.*)/(.*) /$1/$2/index.php [L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
# 4 levels deep
# GET /a/b/c/d-some-thing-here
RewriteRule (.*)/(.*)/(.*)/(.*) /$1/$2/$3/index.php [L]

答案 2 :(得分:0)

的.htaccess

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) ./index.php?__path__=$1&%{QUERY_STRING}

的index.php

$path = '';
if (is_array($_GET) && array_key_exists('__path__', $_GET)) {
    $path = trim($_GET['__path__']);
}
$path = trim($path, '/');
//you can use $path, path can be "a", "a/b" or "a/b/c" for your samples