重写路径段的任意数量的查询参数 [英] Rewriting an arbitrary number of path segments to query parameters

查看:112
本文介绍了重写路径段的任意数量的查询参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的.htaccess规则:

 重写规则viewshoplatest /(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/ (。*)/(。*)/(。*)/(。*)/(。*)/(。*)/(。*)/(。*)/(。*)/ $ /viewshoplatest.php?$1=$2&$3=$4&$5=$6&$7=$8&$9=$10&$11=$12&$13=$14&$15=$16

它应该映射的URL是这样的:

<$p$p><$c$c>http://www.veepiz.com/viewshoplatest/start/10/end/10/filter/0/ownerid/0/sortby/date/sortdir/DESC/cat/0/scat/0/

这样:

<$p$p><$c$c>http://www.veepiz.com/viewshoplatest.php?start=0&end=10&filter=0&ownerid=0&sortby=date&sortdir=DESC&cat=0&scat=0

在我的链接,点击打印 $ _ GET 变量,我得到这样的:

 阵列([开始] =&GT; 10月底] =&GT; 10 [过滤器] =&GT; 0 OWNERID] =&GT; 0 sortby] =&GT; START0 [启动1] =&GT; START2 [start3] =&GT; start4 [start5] =&GT; start6)

任何想法,为什么它的表现不好?


好吧,我已经通过重写规则来解决了这个

 重写规则viewshoplatest/start/(.*)/end/(.*)/filter/(.*)/ownerid/(.*)/sortby/(.*)/sortdir/(.*)/cat/(.*)/scat/(.*)/$ /viewshoplatest.php?start=$1&end=$2&filter=$3&ownerid=$4&sortby=$5&sortdir=$6&cat=$7&scat=$8


解决方案

首先:你不应该使用 * 如果你能更具体,非常相似。这种情况下, [^ /] + 。由于多个。* 可造成巨大的回溯。所以:

 重写规则^viewshoplatest/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ /viewshoplatest.php?$1=$2&$3=$4&$5=$6&$7=$8&$9=$10&$11=$12&$13=$14&$15=$16

您可以使用一个像花使用RegexBuddy 看到这些常规的前pressions如何处理的差异。

但是,因为mod_rewrite的确实只允许引用第一九组(见<一href=\"http://stackoverflow.com/questions/3655893/another-mod-rewrite-problem/3656017#3656017\">Tim’s回答),你可以使用一个迭代的方法,并可以同时处理一个参数:

 重写规则^ viewshoplatest /([^/]+)/([^/]+)/([^/]+/[^/]+/.*)$ / viewshoplatest / $ 3〜$ 1 = $ 2 [QSA,N]
重写规则^ viewshoplatest /([^ /] +)/([^ /] +)/([^ /] *)/ $ /viewshoplatest.php?$1=$2&$3 [QSA,L]

第一条规则将处理在同一时间(除了最后一对)一个参数对通过追加到已经存在的(见的 QSA 的标志),然后重新开始重写操作不增加内部递归计数器(见的 N 的标志)。然后第二个规则将改写最后一个参数对(或只是名称),结束迭代。

但由于使用的 N 的标志可能是危险的,因为它会导致无限递归,你也可以使用PHP来解析请求的路径:

  $ _ SERVER ['REQUEST_URI_PATH'] = parse_url($ _ SERVER ['REQUEST_URI'],PHP_URL_PATH);
$段=破灭('/',修剪($ _ SERVER ['REQUEST_URI_PATH'],'/'));
array_shift($段); //删除路径preFIX/ viewshoplatest
为($ i = 0,$ N =计数($段); $ I&LT; $ N;){
    $ _GET [rawurlde code($段[$ I ++])=($ I&LT; $ N)? rawurlde code($段[$ I ++]):空;
}

现在你只需要这条规则通过将请求传递:

 重写规则^ viewshoplatest(/ | $)/viewshoplatest.php [L]

I have this .htaccess rule:

RewriteRule viewshoplatest/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)/$ /viewshoplatest.php?$1=$2&$3=$4&$5=$6&$7=$8&$9=$10&$11=$12&$13=$14&$15=$16

It should map a URL like this:

http://www.veepiz.com/viewshoplatest/start/10/end/10/filter/0/ownerid/0/sortby/date/sortdir/DESC/cat/0/scat/0/

to this:

http://www.veepiz.com/viewshoplatest.php?start=0&end=10&filter=0&ownerid=0&sortby=date&sortdir=DESC&cat=0&scat=0

When I click on link and print $_GET variables I get this:

Array ( [start] => 10 [end] => 10 [filter] => 0 [ownerid] => 0 [sortby] => start0 [start1] => start2 [start3] => start4 [start5] => start6 )

Any ideas as to why it’s behaving badly?


Ok i have fixed this by rewriting the rule to

RewriteRule viewshoplatest/start/(.*)/end/(.*)/filter/(.*)/ownerid/(.*)/sortby/(.*)/sortdir/(.*)/cat/(.*)/scat/(.*)/$ /viewshoplatest.php?start=$1&end=$2&filter=$3&ownerid=$4&sortby=$5&sortdir=$6&cat=$7&scat=$8

解决方案

First of all: You shouldn’t use .* if you can be more specific, like in this case [^/]+. Because multiple .* can cause immense backtracking. So:

RewriteRule ^viewshoplatest/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ /viewshoplatest.php?$1=$2&$3=$4&$5=$6&$7=$8&$9=$10&$11=$12&$13=$14&$15=$16

You can use a took like RegexBuddy to see the difference in how these regular expressions are processed.

But since mod_rewrite does only allow to reference the first nine groups (see Tim’s answer), you could use an iterative approach and process one parameter at a time:

RewriteRule ^viewshoplatest/([^/]+)/([^/]+)/([^/]+/[^/]+/.*)$ /viewshoplatest/$3?$1=$2 [QSA,N]
RewriteRule ^viewshoplatest/([^/]+)/([^/]+)/([^/]*)/?$ /viewshoplatest.php?$1=$2&$3 [QSA,L]

The first rule will process one parameter pair at a time (except the last pair) by append it to the already existing ones (see QSA flag) and then restart the rewriting process without incrementing the internal recursion counter (see N flag). The second rule will then rewrite the last parameter pair (or just the name) and end the iteration.

But since using the N flag might be dangerous as it can cause an infinite recursion, you could also use PHP to parse the requested path:

$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$segments = implode('/', trim($_SERVER['REQUEST_URI_PATH'], '/'));
array_shift($segments); // remove path prefix "/viewshoplatest"
for ($i=0, $n=count($segments); $i<$n; ) {
    $_GET[rawurldecode($segments[$i++])] = ($i < $n) ? rawurldecode($segments[$i++]) : null;
}

Now you just need this rule to pass the request through:

RewriteRule ^viewshoplatest(/|$) /viewshoplatest.php [L]

这篇关于重写路径段的任意数量的查询参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆