Самый простой способ, если вы можете указать 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 запускать forum-rewriter.pl
один раз для каждого процесса httpd во время запуска. Каждый раз, когда шаблон 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 «заменить all foo_bar
в пути на foo=bar
в строке запроса».