【问题标题】:Rewriting an arbitrary number of path segments to query parameters重写任意数量的路径段以查询参数
【发布时间】:2010-09-07 04:55:56
【问题描述】:

我有这个 .htaccess 规则:

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

它应该像这样映射一个 URL:

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

到这里:

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

当我点击链接并打印 $_GET 变量时,我得到了这个:

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

关于它为什么表现不佳的任何想法?


好的,我已经通过重写规则来解决这个问题

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

【问题讨论】:

  • 在我看来,当它达到 9 美元以上时,它会以 10 美元及以上的价格调用 1 美元

标签: apache mod-rewrite url-rewriting


【解决方案1】:

首先:如果你可以更具体一点,你不应该使用.*,比如在这种情况下[^/]+。因为多个.* 会导致巨大的回溯。所以:

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

您可以使用 RegexBuddy 来查看这些正则表达式处理方式的差异。

但由于 mod_rewrite 只允许引用前九组(请参阅Tim’s answer),您可以使用迭代方法并一次处理一个参数:

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

第一条规则将一次处理一个参数对(最后一对除外),方法是将其附加到已经存在的参数对(参见 QSA 标志),然后重新开始重写过程而不增加内部递归计数器(见 N 标志)。然后第二条规则将重写最后一个参数对(或只是名称)并结束迭代。

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

$_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;
}

现在你只需要这条规则来传递请求:

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

【讨论】:

  • 上面的小修正:explode() REQUEST_URI_PATH,而不是 implode()。 :)
【解决方案2】:

只是为了扩展您发现的内容,您只能定义九个组用作反向引用,这就是为什么重写脚本 sans-query 字符串并让脚本检查 REQUEST_URI 的原因通常是一个更好的主意。需要解析大量数据的情况。

来自the documentation

反向引用是 形成 $N (N=0..9),这将是 替换为第 N 个的内容 匹配模式的组

$0 是整个匹配模式,为您提供剩余的九个数字。任何更高的数字都被视为反向引用,后跟一些文字数字字符。

【讨论】:

    猜你喜欢
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    • 2016-04-05
    • 1970-01-01
    • 2010-11-10
    • 2018-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多