Nginx伪静态参数大于$9解决办法

1 篇文章 0 订阅

问题:
&a=$1&b=$2&c=$3&d=$4&e=$5&f=$6&g=$7&h=$8&i=$9&j=$10

Nginx伪静态$9之后就不认了

看到此题后,因为我自己以前并没有做过十个以个参数重写的情况,所以好奇之下测试了一番,果然如此。

思索了一下,恰巧前两天看过一个关于PHP正则替换函数preg_replace()的相关说明,它说正则匹配后,后面调用前面小括号里的数值(称之为逆向引用)时,可以使用的值为0-99,其中0表示匹配成功后整个字符串的值,而1-99则是小括号匹配出来的值。

同时,它又说了,当逆向引用番号超过9时,需要特别注意,因为$10这样的一个逆向引用,它搞不清楚到底是先使用$1再加上字符串0还是直接引用编号为十这个逆向引用,所以要用花括号将具体的番号给包起来,即: ${1}0 、 ${11},这样才不会混乱。

我马上实验了一番,果然Nginx的重写规则是把$10解释为$1加上字符串0,我马上用花括号将10包起来,然后就出问题了:unknown “10” variable。后来几经测试,并不是它不支持10,而是它不支持花括号,因为我括上1-9的时候,也报一样的错。

没办法,于是我就只有从网上找答案,终于找到两个好答案,并经过测试验证确实可行

1.拆分重写规则,使用多条语句来实现目的结果:
首先,假设我访问的地址是

/abcdefghijk

而实际访问地址却是:

/test.php?a=a&b=b&c=c&d=d&e=e&f=f&g=g&h=h&i=i&j=j&k=k

一共十一个参数,拆分成两个,那么Nginx的伪静态规则则这样写:

location /
{
    if (!-e $request_filename)//若访问的地址不是确切存在的某文件,则执行里面的重写规则
    {
        rewrite ^/(.)(.)(.)(.)(.)(.)(.)(.)(.*)$ /tempkey0/a=$1&b=$2&c=$3&d=$4&e=$5&f=$6&g=$7&h=$8&tempkey1=$9;
        //第一条重写语句:将前八个先重写,然后将后面的全打包,放在tempkey1里面,同时将所有的重写语句打包在tempkey0里
    }
    rewrite ^/tempkey0/(.*?)&tempkey1=(.)(.)(.)$ /test.php?$1&i=$2&j=$3&k=$4;
    //第二条重写语句:获取tempkey0,得知需要重写,将前八个打包放在$1里,然后从tempkey1里匹配出从第九个开始的字符,放在$2开始的组里。最后将获得的参数加在test.php后,得最终结果
}

然后我在test.php里写条语句来获取参数,看是否成功获取:

if(isset($_GET))
print_r($_GET);

然后通过浏览器访问地址

/abcdefghijk

得结果:

Array ( [a] => a [b] => b [c] => c [d] => d [e] => e [f] => f [g] => g [h] => h [i] => i [j] => j [k] => k )

于是,就实现了阁下所需的功能。
然后总结,这个并不会有太多限制,只要将待重写路径拆分即可,哪怕几十上百个匹配结果都行,只不过这样就要拆分出多条语句了,但也并无不可,因为多条语句比一条长语句更易读。

2.分组捕获时给匹配结果添加名字。
首先,结匹配结果添加名字,这一点很好理解,可以用PHP里的数组的键名来做参考。PHP数组中,若里面的键并没有给它起特定的键名,那么它的键名就用数字来代替,从0开始,如
array(“a”, “b”, “c” => “c”);//第一个键的键名就是0,第二个键的键名就是1,第三个键因为给它特定了一个键名c,那么它的键名就是c

分组捕获的规则是:

(?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name'exp)

像这样,将匹配的结果给它一个“键名”,然后在逆向引用的时候就直接用它的“键名”了,非常方便,如上面那个例子,Nginx的重写规则如下:

location /
{
    if (!-e $request_filename)
    {
        rewrite ^/(.)(.)(.)(.)(.)(.)(.)(.)(.)(?<n1>.)(?'n2'.)$ /test.php?a=$1&b=$2&c=$3&d=$4&e=$5&f=$6&g=$7&h=$8&i=$9&j=$n1&k=$n2 last;
        //前九个不用管,可以直接使用数字来做“键名”,第十个我用的是小于和大于符号命名为n1,第十一个我用的单引号将之命名为n2,然后在后面的重写路径中就直接逆向引用n1和n2了
    }
}

然后再访问测试,结果无误。同时,此方法同样可以扩展,几十上百个匹配结果时一样可以用,虽然我没测试过。

原文链接:https://zhidao.baidu.com/question/937097964159925972.html

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值