这非常棘手,但这是一个递归遍历给定 REQUEST_URI 的父目录的代码,它支持无限深度。
通过启用 mod_rewrite 和 .htaccess httpd.conf
,然后将此代码放在您.htaccess
的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
存在,但在DOCUMENT_ROOT
.
RewriteRule #1 有一个正则表达式,它将当前的 REQUEST_URI 分成两部分:
- 除了最低的子目录之外的所有子目录
$1
都将在index/foo/bar
这里
$2
将在baz
这里的最低子目录
RewriteCond 检查是否%{DOCUMENT_ROOT}/$1/$2.php
(转换为是否%{DOCUMENT_ROOT}/index/foo/bar/baz.php
)不是有效文件。
如果条件成功,则在内部将其重定向到$1/
此处index/foo/bar/
。
再次重复 RewriteRule #1 的逻辑以使 REQUEST_URI 为(在每次递归之后):
index/foo/bar/
index/foo/
index/
此时 RewriteCond 对规则 #1 失败,因为${DOCUMENT_ROOT}/index.php
那里存在。
我的 RewriteRule #2 表示转发$1.php
是否%{DOCUMENT_ROOT}/$1.php
是有效文件。请注意,RewriteRule #2 具有匹配除最后一个斜杠之外的所有内容并将其放入$1
. 这意味着检查是否%{DOCUMENT_ROOT}/index.php
是一个有效的文件(它确实是)。
此时 mod_rewrite 处理已完成,因为此后两个 RewriteCond 都失败了,因此无法触发进一步的规则,因此%{DOCUMENT_ROOT}/index.php
您的 Apache Web 服务器会及时提供服务。