我正在尝试编写一条规则,以便可以概括,因为传递值的多个页面是不同的。现在我可以这样做:
RewriteRule ^forum/([^/]{1,255})/([\+]{1})/((([a-z]+)([_]{1})([a-zA-Z0-9]+)([/]?))+)$ forum.php?name=$1&$5=$7 [L]
解决诸如:
Nome+del+Forum/+/page_1/action_do
应该返回:
forum.php?name=Nome+del+Forum&page=1&action=do
相反,只取最后一个参数(在这种情况下 action = do ):
forum.php?name=Nome+del+Forum&action=do
我该如何解决?提前谢谢!
答案 0 :(得分:0)
最简单的方法是在网站配置中添加RewriteMap prg:foo
。请注意,据我所知,您无法在RewriteMap
中使用.htaccess
。
如果您有权访问服务器配置文件,请在全局或<VirtualHost>
中添加类似这样的内容:
RewriteMap forum prg:/path/to/forum-rewriter.pl
然后在您选择的.htaccess
尝试:
RewriteRule ^forum/.* ${forum:$0} [QSA]
(在您尝试的RewriteRule
中,您似乎希望匹配以forum/
开头的路径,这就是我在这里所做的。)
接下来,您需要制作forum-rewriter.pl
:
#!/usr/bin/perl
use strict;
use warnings;
$| = 1;
while ($_ = <STDIN>) {
chomp($_);
if (s,^forum/([^/]+)(/\+)?(/.*)?,forum.php?name=$1, && $3) {
my $query_string = $3;
$query_string =~ s,/([^/_]+)_([^/_]+),&$1=$2,g;
$_ .= $query_string;
}
print "$_\n";
}
确保chmod 755 /path/to/forum-rewriter.pl
。
RewriteMap
将使Apache在启动时为每个httpd进程启动forum-rewriter.pl
一次。每次RewriteRule
的模式匹配时,它都会写入forum-rewriter.pl
的标准输入的路径。 forum-rewriter.pl
将在URL上完成其工作(如果有的话)并将结果打印回Apache。
仅供参考,我很容易测试forum-rewriter.pl
。只需运行它并开始发送路径:
$ /tmp/forum-rewriter.pl
forum/Nome+del+Forum/+/page_1/action_do
forum.php?name=Nome+del+Forum&page=1&action=do
forum/Nome+del+Forum/page_1/action_do
forum.php?name=Nome+del+Forum&page=1&action=do
forum/Nome+del+Forum
forum.php?name=Nome+del+Forum
foo
foo
如果您无法使用RewriteMap
,我认为可以使用mod_rewrite
,但我认为这很危险:
RewriteCond %{ENV:SetForumName} =""
RewriteRule ^forum/([^/]+)(/\+)?(/.*)? /forum.php$3?name=$1 [QSA,E=SetForumName:1]
RewriteCond %{ENV:SetForumName} !=""
RewriteRule ^forum.php/([^/_]+)_([^/_]+)(/.*)? /forum.php$3?$1=$2 [N,QSA]
这很危险,因为[N]
导致Apache在第二个RewriteRule
匹配时重新开始处理所有重写规则。如果你不小心,你将创建一个无限循环,Apache将要求500或呱呱叫。还要注意它设置SetForumName
环境变量的副作用。但是,这是我能够找到告诉mod_rewrite在查询字符串中使用foo_bar
的路径中替换所有 foo=bar
的唯一方法。“
答案 1 :(得分:0)
类似于this?
另请参阅this了解更多信息。
基本信息是这些规则
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^(.*/)([^/]+)/([^/]+) $1?$2=$3&%1 [L]
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^([^/]+)/ $1?%1 [L]
将重写以下内容
/mypage/param1/val1/param2/val2/param3/val3/... --->
/mypage?param1=val1¶m2=val2¶m3=val3&...
它接受第一个参数并调用该页面。其余参数将转换为查询字符串。
编辑更多有关代码如何工作的内容。
第一行(和第三行)仅捕获“?”之后的所有内容。这样它就可以添加回重写URL的末尾。同一件事情 可以使用[QSA]标志完成,但我更喜欢这样做 明确地说它是可见的。
该字符串保存在%1变量中。
第二行使用正则表达式将URL拆分为三个部分。
$ 2和$ 3是路径的最后两部分。 1美元就是之前的一切。
所以这个:
/mypage/param1/val1/param2/val2/param3/val3/param4/val4/param5/val5/
成为这个:
$1 $2 $3
/mypage/param1/val1/param2/val2/param3/val3/param4/val4/ param5 val5
并重写为此(为了便于阅读而添加了空格):
/mypage/param1/val1/param2/val2/param3/val3/param4/val4/ ? param5 = val5
如果您的URL使用除斜杠之外的分隔符,则可以修改常规 相应的表达。
[L](“last”)标志阻止其余规则运行。 但是 - 这是关键 - mod_rewrite使用new调用webserver URL和新URL再次通过mod_rewrite发送!这有时被称为mod_rewrite递归,正是你想要的工作。
下一次,接下来的两个部分被剥离并添加 到查询字符串。
此:
$1 $2 $3 %1
/mypage/param1/val1/param2/val2/param3/val3 param4 val4 ? param5=val5
成为这个:
/mypage/param1/val1/param2/val2/param3/val3 ? param4 = val4 & param5=val5
这会一直发生,直到URL的所有部分都转换为 查询字符串的一部分。当发生这种情况时,第二行不匹配 但第四行呢。这就是为您提供调用的最终URL的原因 你想要的节目。上面的链接显示了略有不同的变化的答案 允许不同的规则。
另请注意,mod_rewrite的次数有限制
可以递归。请参阅设置
{。1}} .htaccess和
MaxRedirects
在你的apache conf文件中。