mod_rewrite用于站点上的所有页面(包括子文件夹)到单个php页面

时间:2011-02-25 19:04:09

标签: apache mod-rewrite

我正在将包含许多静态html页面的网站转换为由数据库驱动的网站。我的问题是我不想丢失谷歌已编入索引的内容,因此我想重写通过php脚本发送的请求,该脚本在数据库中查找文件路径以查找内容。我的理解是mod_rewrite最适合这个目的,不幸的是我从未使用它,所以我有点迷失。

我有什么:

www.domain.com/index.html
www.domain.com/page.html?var=123&flag=true
www.domain.com/folder/subfolder/
www.domain.com/folder/subfolder/index.html
www.domain.com/folder/subfolder/new/test.html
www.domain.com/folder/subfolder/new/test.html?var=123&flag=true

我想要什么(我也可能需要对路径进行urlencode)(传递完整的uri也行):

www.domain.com/index.php?page=/index.html OR www.domain.com/index.php?page=www.domain.com/index.html
www.domain.com/index.php?page=/page.html?var=123&flag=true
www.domain.com/index.php?page=/folder/subfolder/
www.domain.com/index.php?page=/folder/subfolder/index.html
www.domain.com/index.php?page=/folder/subfolder/new/test.html
www.domain.com/index.php?page=/folder/subfolder/new/test.html?var=123&flag=true

这是我的第一次:

RewriteEngine On  # Turn on rewriting    
RewriteCond %{REQUEST_URI} .* # Do I even need this?    
^(.*)$ /index.php?page=$1

想法?在此先感谢:)

编辑:

所以我尝试实现Ragnar的解决方案,但是当我使用'RewriteCond $ 1'或在最后一行包含'/'时,我一直遇到500错误。我已经设置了一个test.php文件,它将回显GET _ [“page”],所以我知道重写是正常的。到目前为止,我可以获得一些正确的输出(但仅当我不在root中时),例如:

RewriteEngine on
RewriteRule ^page/(.*)$ test.php?page=$1 [L]

如果我访问页面http://www.domain.com/page/test/subdirectory/page.html?var=123,它将输出'test / subdirectory / page.html'(缺少我需要的查询字符串)。但是,如果我使用这个例子:

RewriteEngine on
RewriteRule ^(.*)$ test.php?page=$1 [L]

如果我访问http://www.domain.com/page/test/subdirectory/page.html?var=123,它只会输出'test.php',这完全令人困惑。想法?

编辑#2:

看来我一直都是这么错。我只是想在我的php脚本页面中使用完整的uri。做我想做的最终工作解决方案如下:

Options +FollowSymlinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /test.php

然后在我的php脚本中,我可以使用$ _SERVER ['REQUEST_URI']来获得我需要的东西。我知道这应该比我尝试的更容易......

2 个答案:

答案 0 :(得分:2)

我建议您查看Apache URL Rewriting Guide,它包含有关使用示例重写的大量信息。

如果我理解正确,你应该可以使用这样的东西

RewriteEngine on
RewriteCond $1 
RewriteRule ^(.*)$ index.php/?page=$1 [L]

哪个代码与您发布的代码非常相似。如果您想了解更多信息,请具体说明您的问题。

答案 1 :(得分:2)

不需要这么多行,只会让事情复杂化。

您需要的只是.htaccess中的两行:

rewriteengine on
#rewriterule-: ar1 path =relative. ar2 if relative, that to rewritebase.
rewriterule !^foo/bar/index\.php$ /foo/bar/index.php
#..assert ar1 dismatches correct url

在PHP中

您可以使用以下方法在PHP中输出重写的第一个输入:

<?=$_SERVER['REQUEST_URI'];

这会给你所有的力量,让你做所有的事情。只需手动解析$_SERVER["REQUEST_URI"],您就可以echo完全不同的页面,具体取决于$_SERVER["REQUEST_URI"]的值。


秒错误

请注意,您的服务器可能会在重写之前执行路径或错误路径。 (如果没有服务器权限,则无法覆盖此行为。)例如,如果用户访问/foo////,您可能只会看到/foo//foo。例如,如果用户访问///foo,您可能只会看到/foo。例如,如果用户访问/a/../foo,您可能只会看到/foo。例如,如果用户访问/a//b/../../foo,您可能只会看到/foo/a/foo [因为错误的生产服务器会在/的上下文中将多个..视为不同, no kidding ]。


电路中断

重写与htaccess相同的cin电路中断∙父文件夹∙相对解释的重写∙arg2。 (首先,我个人会禁用电路中断以减少规则的复杂性,但似乎没有办法这样做。)

断路解决方案:

rewriteengine on
#rewriterule-: ar1 path =relative. ar2 if relative, that to rewritebase.
rewriterule ^ /foo/bar/index.php
#..circuit-breaking, so assert ar2 if absolute, htaccess parentfolder =root, else, htaccess parentfolder not in interpreted ar2.

电路中断和重写基未使用

断路需要:

  1. arg2 [rewriterule]⇌绝对。和htaccess父文件夹⇌根。
  2. arg2⇌亲戚。并且该文件夹不在解释的arg2中。
  3. 因此,当该文件夹≠root时,电路中断需要arg2⇌relative。当arg2⇌相对时,电路中断需要该文件夹⇌不在解释arg2⏋中。

    假设我们需要断路器和一个解释为arg2的htaccess父文件夹,所以我们通过rewritebase编辑arg2:

    rewriteengine on
    #rewriterule-: ar1 path =relative. ar2 if relative, that to rewritebase.
    rewriterule ^ bar/index.php
    #..circuit-breaking, so assert ar2 if absolute, htaccess parentfolder =root, else, htaccess parentfolder not in interpreted ar2.
    rewritebase /foo
    #..needs to be absolute [</> starting]. pathing [eg </../a/..> and </../..///ran/dom-f/oobar/./././../../..////////.//.>] allowed