使用url作为参数将每个请求重写为一个文件

时间:2014-10-27 19:13:24

标签: apache .htaccess mod-rewrite

我正在用PHP编写一个小型CMS,需要将所有请求重定向到该文件(在我的案例中称为cms.php)。例如

/~ps0ke/ -> /~ps0ke/cms.php?path=index.html
/~ps0ke/projects/cms.html -> /~ps0ke/cms.php?path=projects/cms.html

等等。如果lang位于目录之前,还会设置en/参数。这应该不重要,因为我在添加多语言支持之前存在问题。现在我正在使用Apache和以下.htaccess来实现重写:

RewriteEngine On
RewriteBase /~ps0ke/

# Serve index.html via cms.php when base dir or index.html is requested. Also
# set the language.
RewriteRule ^((en)/)?(index.html)?$ cms.php?lang=$2&path=index.html [NC,L]

# Serve everything else via cms.php. Also set the language.
# Serving from the page subdirectory is due to a problem with all-wildcard
# RewriteRule. This might be fixed.
RewriteRule ^((en)/)?page/(.*)$ cms.php?lang=$2&path=$3 [NC,L,B]

您可能会注意到page/和实际路径之间还有RewriteBase。我这样做是因为只需匹配

RewriteRule ^((en)/)?(.*)$ cms.php?lang=$2path=$3 [NC,L,B]

根本不起作用。我不明白为什么。当我使用上述规则时输出$_GET会导致

Array
(
    [lang] => 
    [path] => cms.php
)

无论实际的GET路径如何,path GET-Variable始终设置为脚本的名称。我只是不明白为什么。

我不希望包含page/前缀的原因是它保持向后兼容性。 CMS专门用于提供正常的文件结构,并仅从文件系统构建其导航等。因此,在GET路径中表示实际的真实文件结构会很好。因此,即使有人再次删除CMS,链接仍然有效。

更简单的参考我在Apache手册中输入了所用的选项:

  

NC | NOCASE

     

使用[NC]标志会使RewriteRule在a中匹配   不区分大小写的方式。也就是说,它不关心是否是字母   在匹配的URI中显示为大写或小写。

     

B(逃避反向引用)

     

[B]标志指示RewriteRule转义非字母数字   应用转换前的字符。

     

→|最后

     

[L]标志使mod_rewrite停止处理规则集。在   大多数情况下,这意味着如果规则匹配,则没有进一步的规则   将被处理。这对应于Perl中的最后一个命令,或   C中的break命令。使用此标志指示当前   应立即应用规则而不考虑进一步的规则。

任何帮助(修复或解释)表示赞赏!提前谢谢!

1 个答案:

答案 0 :(得分:1)

您遇到此问题是因为您的规则正在执行两次。你可以通过避免所有资源(js,image,css等)重写而不让它第二次运行来阻止它。

你的规则如下:

RewriteEngine On
RewriteBase /~ps0ke/

# avoid any rules for resources and 2nd time:
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_URI} \.(?:jpe?g|gif|bmp|png|tiff|css|js)$ [NC,OR]
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]

# Serve index.html via cms.php when base dir or index.html is requested. Also
# set the language.
RewriteRule ^((en)/)?(index.html)?$ cms.php?lang=$2&path=index.html [NC,L,QSA]

# Serve everything else via cms.php. Also set the language.
# Serving from the page subdirectory is due to a problem with all-wildcard
# RewriteRule. This might be fixed.
RewriteRule ^((en)/)?(.*)$ cmas.php?lang=$2path=$3 [NC,L,QSA]