user2977468
user2977468

Reputation: 183

Rewrite directive results in additional $_GET parameter using Nginx

We just switched from Apache to nginx at my office.

The apaches rewrite rules looked like the following:

RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/$ /main.php?A=$1&B=$2&C=$3&D=$4&E=$5 [L]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)/$ /main.php?A=$1&B=$2&C=$3&D=$4 [L]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/$ /main.php?A=$1&B=$2&C=$3 [L]
RewriteRule ^([^/]*)/([^/]*)/$ /main.php?A=$1&B=$2 [L]
RewriteRule ^([^/]*)/$ /main.php?A=$1 [L]

The new Nginx rules are as follows:

rewrite ^([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/$ /main.php?A=$1&B=$2&C=$3&D=$4&E=$5 last;
rewrite ^([^/]*)/([^/]*)/([^/]*)/([^/]*)/$ /main.php??A=$1&B=$2&C=$3&D=$4 last;
rewrite ^([^/]*)/([^/]*)/([^/]*)/$ /main.php?A=$1&B=$2&C=$3 last;
rewrite ^([^/]*)/([^/]*)/$ /main.php?A=$1&B=$2 last;
rewrite ^([^/]*)/$ /main.php?A=$1 last;

Here's the issue, assuming we're accessing domain.com/frog/lemon/

<?php

/* Using Apache */
print_r( $_GET );
Array( [A] => 'frog' [B] => 'lemon' )

/* Using Nginx */
print_r( $_GET );
Array( [A] => [B] => [C] => 'lemon' )

?>

What's causing the additional array param ?

Bonus: I'm sure there a smarter way to code what I have above, how would you write your rewrites?

Upvotes: 0

Views: 95

Answers (1)

FrancescoMM
FrancescoMM

Reputation: 2960

Probably the paths are passed with an initial / which before they didn't have?

Path /frog/lemon/ will get caught by rule

^([^/]*)/([^/]*)/([^/]*)/$

as [^/]* will catch also ZERO chars.

* means: zero or more chars

+ means: at least one char

If so, /frog/lemon/

becomes

^(zero chars here)/frog/lemon/$

hence A='',B='frog',C='lemon'

To fix it, try putting a / before the [^/]* like this:

rewrite ^/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/$ /main.php?A=$1&B=$2&C=$3&D=$4&E=$5 last;
rewrite ^/([^/]*)/([^/]*)/([^/]*)/([^/]*)/$ /main.php??A=$1&B=$2&C=$3&D=$4 last;
rewrite ^/([^/]*)/([^/]*)/([^/]*)/$ /main.php?A=$1&B=$2&C=$3 last;
rewrite ^/([^/]*)/([^/]*)/$ /main.php?A=$1&B=$2 last;
rewrite ^/([^/]*)/$ /main.php?A=$1 last;

Maybe also put + instead of *, in all the params that can't be empty (can't be frog//lemon)

rewrite ^([^/]+)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/$ /main.php?A=$1&B=$2&C=$3&D=$4&E=$5 last;
rewrite ^/([^/]+)/([^/]*)/([^/]*)/([^/]*)/$ /main.php??A=$1&B=$2&C=$3&D=$4 last;
rewrite ^/([^/]+)/([^/]*)/([^/]*)/$ /main.php?A=$1&B=$2&C=$3 last;
rewrite ^/([^/]+)/([^/]*)/$ /main.php?A=$1&B=$2 last;
rewrite ^/([^/]+)/$ /main.php?A=$1 last;

Upvotes: 2

Related Questions