这是非常棘手的,但这里有一个代码递归地遍历给定 REQUEST_URI 的父目录,并且它支持无限深度。
通过启用 mod_rewrite 和 .htaccesshttpd.conf
然后将此代码放入您的.htaccess
under DOCUMENT_ROOT
目录:
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# If the request is for a valid file
RewriteCond %{REQUEST_FILENAME} -f [OR]
# If the request is for a valid link
RewriteCond %{REQUEST_FILENAME} -l
# don't do anything
RewriteRule ^ - [L]
# if current ${REQUEST_URI}.php is not a file then
# forward to the parent directory of current REQUEST_URI
RewriteCond %{DOCUMENT_ROOT}/$1/$2.php !-f
RewriteRule ^(.*?)/([^/]+)/?$ $1/ [L]
# if current ${REQUEST_URI}.php is a valid file then
# load it be removing optional trailing slash
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.*?)/?$ $1.php [L]
解释:
假设原始 URI 是:/index/foo/bar/baz
。还要说一下%{DOCUMENT_ROOT}/index.php
存在但不存在其他 php 文件DOCUMENT_ROOT
.
RewriteRule #1 有一个正则表达式,它将当前的 REQUEST_URI 分成两部分:
- 除最低子目录外的所有子目录都进入
$1
这将是index/foo/bar
here
- 最低子目录进入
$2
这将是baz
here
RewriteCond 检查是否%{DOCUMENT_ROOT}/$1/$2.php
(这意味着是否%{DOCUMENT_ROOT}/index/foo/bar/baz.php
) is NOT一个有效的文件。
如果条件成功,则会在内部重定向到$1/
这是index/foo/bar/
here.
再次重复 RewriteRule #1 的逻辑以使 REQUEST_URI 为(每次递归之后):
index/foo/bar/
index/foo/
index/
此时,RewriteCond 对于规则#1 失败,因为${DOCUMENT_ROOT}/index.php
存在于那里。
我的 RewriteRule #2 表示转发到$1.php
if %{DOCUMENT_ROOT}/$1.php
是一个有效的文件。请注意,RewriteRule #2 的正则表达式可以匹配除最后一个斜杠之外的所有内容,并将其放入$1
。这意味着检查是否%{DOCUMENT_ROOT}/index.php
是一个有效的文件(确实是)。
此时 mod_rewrite 处理已完成,因为此后两个 RewriteCond 都失败,因此无法触发进一步的规则,因此%{DOCUMENT_ROOT}/index.php
由您的 Apache Web 服务器提供适当的服务。