Apache Htaccess递归文件重写

Apache Htaccess递归文件重写,apache,.htaccess,file,mod-rewrite,recursion,Apache,.htaccess,File,Mod Rewrite,Recursion,我想知道是否有更好的方法来实现这种排序或重定向: # Apache configuration Options -Indexes Options +FollowSymLinks # Rewrite engine configuration RewriteEngine On RewriteBase / # Force domain www (302 redirect) RewriteCond %{HTTP_HOST} ^([^\.]+\.[^\.0-9]+)$ RewriteRule

我想知道是否有更好的方法来实现这种排序或重定向:

# Apache configuration

Options -Indexes
Options +FollowSymLinks


# Rewrite engine configuration

RewriteEngine On
RewriteBase /


# Force domain www (302 redirect)

RewriteCond %{HTTP_HOST} ^([^\.]+\.[^\.0-9]+)$
RewriteRule ^/?(.*)$ http://www.%1/$1 [L,R=302]


# Request redirection (/module/TLD/module/DOMAIN/module/SUB/data/public/...)

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^(.+)\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%3/module/%2/module/%1/data/public/%{REQUEST_URI} -f
RewriteRule ^/?(.+)$        /module/%3/module/%2/module/%1/data/public/$1 [L]

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^(.+)\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%3/module/%2/module/%1/data/public/%{REQUEST_URI}/index.php -f
RewriteRule ^/?(.+)/?$        /module/%3/module/%2/module/%1/data/public/$1/index.php [L]

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^(.+)\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%3/module/%2/module/%1/data/public/%{REQUEST_URI}/index.html -f
RewriteRule ^/?(.+)/?$        /module/%3/module/%2/module/%1/data/public/$1/index.html [L]

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^(.+)\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%3/module/%2/module/%1/data/public/index.php -f
RewriteRule ^/?$            /module/%3/module/%2/module/%1/data/public/index.php [L]

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^(.+)\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%3/module/%2/module/%1/data/public/index.html -f
RewriteRule ^/?$            /module/%3/module/%2/module/%1/data/public/index.html [L]


# Request redirection (/module/TLD/module/DOMAIN/data/public/...)

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%2/module/%1/data/public/%{REQUEST_URI} -f
RewriteRule ^/?(.+)$        /module/%2/module/%1/data/public/$1 [L]

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%2/module/%1/data/public/%{REQUEST_URI}/index.php -f
RewriteRule ^/?(.+)/?$        /module/%2/module/%1/data/public/$1/index.php [L]

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%2/module/%1/data/public/%{REQUEST_URI}/index.html -f
RewriteRule ^/?(.+)/?$        /module/%2/module/%1/data/public/$1/index.html [L]

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%2/module/%1/data/public/index.php -f
RewriteRule ^/?$            /module/%2/module/%1/data/public/index.php [L]

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%2/module/%1/data/public/index.html -f
RewriteRule ^/?$            /module/%2/module/%1/data/public/index.html [L]


# Request redirection (/module/TLD/data/public/...)

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%1/data/public/%{REQUEST_URI} -f
RewriteRule ^/?(.+)$        /module/%1/data/public/$1 [L]

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%1/data/public/%{REQUEST_URI}/index.php -f
RewriteRule ^/?(.+)/?$        /module/%1/data/public/$1/index.php [L]

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%1/data/public/%{REQUEST_URI}/index.html -f
RewriteRule ^/?(.+)/?$        /module/%1/data/public/$1/index.html [L]

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%1/data/public/index.php -f
RewriteRule ^/?$            /module/%1/data/public/index.php [L]

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%1/data/public/index.html -f
RewriteRule ^/?$            /module/%1/data/public/index.html [L]


# Request redirection (/data/public/...)

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{DOCUMENT_ROOT}/data/public/%{REQUEST_URI} -f
RewriteRule ^/?(.+)$        /data/public/$1 [L]

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{DOCUMENT_ROOT}/data/public/%{REQUEST_URI}/index.php -f
RewriteRule ^/?(.+)/?$        /data/public/$1/index.php [L]

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{DOCUMENT_ROOT}/data/public/%{REQUEST_URI}/index.html -f
RewriteRule ^/?(.+)/?$        /data/public/$1/index.html [L]

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{DOCUMENT_ROOT}/data/public/index.php -f
RewriteRule ^/?$            /data/public/index.php [L]

RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{DOCUMENT_ROOT}/data/public/index.html -f
RewriteRule ^/?$            /data/public/index.html [L]


# Request redirection (main index file)

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /index.php [L,PT]
例如,我重定向一个请求,如
http://www.testdomain.com/test/file.css
到这些可能的路径:

  • /module/com/module/testdomain/module/www/data/public/test/file.css
  • /module/com/module/testdomain/data/public/test/file.css
  • /module/com/data/public/test/file.css
  • /data/public/test/file.css

如果这些路径都不正确,我就回到
/index.php
。对于uri为空的请求,我尝试像
http://www.testdomain.com/index.html
http://www.testdomain.com/index.php
。有没有更好的方法来实现这种重写?

你试图做的是冗长而有些奇怪的事情,而奇怪的本质正是我感兴趣的地方。:-)然而,我想你一定有你的理由

冗长的一个优点是,您可以在一个
.htaccess
文件中准确地定义您想要实现的目标,因此,如果它没有损坏。。。虽然您在这个逻辑链中执行了相当多的regexp和stat探测,但我不确定我会推荐这作为一种通用方法

此外,任何“选项”也会影响您试图实现的内容的语义,但您可以利用重写引擎的递归特性,例如,如果
/module/TLD/module/DOMAIN/module/SUB/data/public/
,则必须在该上下文中解释URI,因此类似于

# If we have a file match, then we're done
RewriteCond %{REQUEST_FILENAME}  -f
RewriteRule ^                    -  [L]

# Skip the four directory rewrites except on first pass
RewriteCond %{ENV:REDIRECT_PASS} !=""
RewriteRule ^                    -  [E:PASS=OK, SKIP=5]
RewriteRule ^                    -  [E:PASS=OK]

# Redirect to correct subdirectory
RewriteCond %{HTTP_HOST}    ^(.+)\.([^.]+)\.([^.\d]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%3/module/%2/module/%1/data/public/   -d
RewriteRule ^.*$            /module/%3/module/%2/module/%1/data/public/$0  [L]

RewriteCond %{HTTP_HOST}    ^.+\.([^.]+)\.([^.\d]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%2/module/%1/data/public/             -d
RewriteRule ^.*$            /module/%2/module/%1/data/public/$0            [L]

RewriteCond %{HTTP_HOST}    ^.+\.([^.\d]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%1/data/public/                       -d
RewriteRule ^.*$            /module/%1/data/public/$0                     [L]

RewriteRule ^.*$           /data/public/$0                                [L]

# Etc ... your URIs now include the correct prefix.

  • ^
    始终匹配
  • subst字符串中的裸
    -
    表示保持不变
  • 不要在PER_DIR(例如
    .htaccess
    模式)中包含前导的
    /
  • $0
    是整个匹配字符串——如果需要整个字符串,请使用括号保存
  • 您不需要在
    []
    选择器中转义
  • 阅读有关设置和使用环境变量的内容。如果设置了变量PASS,则在内部重定向之后,它将显示为REDIRECT\u PASS

  • 您还需要启用重写日志并检查日志以进行调试。玩得开心。

    您可以使用
    index\(php | html)将
    index.php
    index.html
    路径编译为一个路径
    并将其作为变量引用。@hjpotter92,不,您不能——至少不能对
    Rewritecond
    中的第一个参数这样做,因为这是一个字符串而不是一个模式。:(我知道这是一种不常见的重写用法啊哈。谢谢您的回复和注释!经过一些测试。我在重写
    索引时遇到问题。(php | html)
    文件位于现有目录中。例如,
    /data/public/test/
    是一个目录,但我想在uri为
    /test/
    时将其重定向到
    /data/public/test/index.(php | html)
    。这就是它的用途:)