nginx rewrite rule to convert URL segments to query string parameters

Posted by Nick on Server Fault See other posts from Server Fault or by Nick
Published on 2013-09-29T18:04:10Z Indexed on 2014/06/12 9:27 UTC
Read the original article Hit count: 192

Filed under:
|

I'm setting up an nginx server for the first time, and having some trouble getting the rewrite rules right for nginx.

The Apache rules we used were:

See if it's a real file or directory, if so, serve it, then send all requests for / to Director.php

DirectoryIndex Director.php

If the URL has one segment, pass it as rt

 RewriteRule ^/([a-zA-Z0-9\-\_]+)/$ /Director.php?rt=$1 [L,QSA]

If the URL has two segments, pass it as rt and action

RewriteRule ^/([a-zA-Z0-9\-\_]+)/([a-zA-Z0-9\-\_]+)/$ /Director.php?rt=$1&action=$2 [L,QSA]

My nginx config file looks like:

server {
...

location / {
   try_files $uri $uri/ /index.php;
}    

location ~ \.php$ {
      fastcgi_pass unix:/var/run/php5-fpm.sock;
      fastcgi_index  index.php;
      fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
      include        fastcgi_params;
   }
}

How do I get the URL segments into Query String Parameters like in the Apache rules above?

UPDATE 1

Trying Pothi's approach:

# serve static files directly
location ~* ^.+\.(jpg|jpeg|gif|css|png|js|ico|html)$ {
   access_log off;
   expires 30d;
}


location / {
   try_files $uri $uri/ /Director.php;
   rewrite "^/([a-zA-Z0-9\-\_]+)/$" "/Director.php?rt=$1" last;
   rewrite "^/([a-zA-Z0-9\-\_]+)/([a-zA-Z0-9\-\_]+)/$" "/Director.php?rt=$1&action=$2" last;
}


location ~ \.php$ {
   fastcgi_pass unix:/var/run/php5-fpm.sock;
   fastcgi_index  index.php;
   fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
   include        fastcgi_params;
}

This produces the output No input file specified. on every request. I'm not clear on if the .php location gets triggered (and subsequently passed to php) when a rewrite in any block indicates a .php file or not.

UPDATE 2

I'm still confused on how to setup these location blocks and pass the parameters.

location /([a-zA-Z0-9\-\_]+)/ {
   fastcgi_pass unix:/var/run/php5-fpm.sock;
   fastcgi_index  index.php;
   fastcgi_param  SCRIPT_FILENAME  ${document_root}Director.php?rt=$1{$args};
   include        fastcgi_params;
}

UPDATE 3

It looks like the root directive was missing, which caused the No input file specified. message. Now that this is fixed, I get the index file as if the URL were / on every request regardless of the number of URL segments.

It appears that my location regular expression is being ignored.

My current config is:

# This location is ignored:
location /([a-zA-Z0-9\-\_]+)/ {
   fastcgi_pass unix:/var/run/php5-fpm.sock;
   fastcgi_index  Director.php;
   set $args $query_string&rt=$1;
   fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
   include        fastcgi_params;
}

location / {
   try_files $uri $uri/ /Director.php;
}

location ~ \.php$ {
   fastcgi_pass unix:/var/run/php5-fpm.sock;
   fastcgi_index  Director.php;
   fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
   include        fastcgi_params;
}

© Server Fault or respective owner

Related posts about nginx

Related posts about rewrite