nginx rewrite rule to convert URL segments to query string parameters
- by Nick
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;
}