将站点上的所有页面(包括子文件夹)的 mod_rewrite 写入单个 php 页面
Posted
技术标签:
【中文标题】将站点上的所有页面(包括子文件夹)的 mod_rewrite 写入单个 php 页面【英文标题】:mod_rewrite for all pages (including subfolders) on a site to a single php page 【发布时间】:2011-07-04 12:51:14 【问题描述】:我正在将包含许多静态 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'] 来获得我需要的东西。我知道这应该比我尝试的更容易......
【问题讨论】:
如果 Edit #2 是解决方案,您应该将其作为解决方案发布,然后在几个小时后检查。 【参考方案1】:我建议您查看Apache URL Rewriting Guide,它包含有关使用示例重写的大量信息。
如果我理解正确,你应该可以使用这样的东西
RewriteEngine on
RewriteCond $1
RewriteRule ^(.*)$ index.php/?page=$1 [L]
这与您发布的代码非常相似。如果您想了解更多信息,请具体说明您的问题。
【讨论】:
感谢您的回复,很高兴看到我在正确的轨道上。在最后一行对 $1 进行 urlencoding 的任何提示? @veerman,见here。 @veerman,只要是透明重定向(即不是重定向到新域),您就不必费心传递$1
。只需进行透明重定向,您就可以使用通常的方式从脚本中读取路径:echo $_SERVER['REQUEST_URI']
。我的答案。【参考方案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 中输出 rewriterule 的第一个输入:
<?=$_SERVER['REQUEST_URI'];
这会给你所有的力量,让你做所有的事情。只需手动解析$_SERVER["REQUEST_URI"]
,您就可以根据$_SERVER["REQUEST_URI"]
的值对echo
完全不同的页面。
安全漏洞
请注意,您的服务器可能会在重写之前进行路径或错误路径。 (如果没有服务器权限,您不能覆盖此行为。)例如,如果用户访问/foo////
,您可能只会看到/foo/
或/foo
。例如,如果用户访问///foo
,您可能只会看到/foo
。例如,如果用户访问/a/../foo
,您可能只会看到/foo
。例如,如果用户访问/a//b/../../foo
,您可能只会看到/foo
或/a/foo
[因为有缺陷的生产服务器在..
的上下文中将多个/
视为不同,不开玩笑] .
带断路
在与 htaccess∙parentfolder∙相对解释的 rewriterule∙arg2 相同的 cin 上重写电路中断。 (首先,我个人会禁用断路器以降低规则复杂性,但似乎没有办法这样做。)
断路解决方案:
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.
电路中断和重写基础的非设计用途
电路中断需要:
-
arg2 [重写] ⇌绝对。和 htaccess 父文件夹 ⇌根。
arg2 ⇌相对的。并且该文件夹不在解释的 arg2 中。
所以当那个文件夹≠根目录时,断路需要arg2 ⇌相对的。当 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
【讨论】:
以上是关于将站点上的所有页面(包括子文件夹)的 mod_rewrite 写入单个 php 页面的主要内容,如果未能解决你的问题,请参考以下文章
jQuery - 如果所有子元素都具有相同的类,则将附加类添加到页面上的另一个元素