url-rewritingnginx

Rewrite all requests to index.php with nginx


In my apache configuration I have the following simple rewrite rule which

  1. unless file exists will rewrite to index.php
  2. on the urls you never see the file extension (.php)

how can I rewrite this in nginx?

#
# Redirect all to index.php
#
RewriteEngine On

# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteCond %{REQUEST_URI} (/[^.]*|\.)$ [NC]
RewriteRule .* index.php [L]

Here's how my nginx server block looks like now, but it doesn't work :(

root /home/user/www;
index index.php;

# Make site accessible from http://localhost/
server_name some-domain.dev;


###############################################################
# exclude /favicon.ico from logs
location = /favicon.ico {
    log_not_found off;
    access_log off;
}   

##############################################################
# Disable logging for robots.txt
location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
}   

##############################################################
# Deny all attempts to access hidden files such as 
# .htaccess, .htpasswd, .DS_Store (Mac).
location ~ /\. {
    deny all;
    access_log off;
    log_not_found off;
}   

##############################################################
#   
location / { 
    include /etc/nginx/fastcgi_params;
    fastcgi_param   SCRIPT_FILENAME  $document_root/index.php$args;
    fastcgi_pass    127.0.0.1:9000;
}   

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

###############################################################
# redirect server error pages to the static page /50x.html
error_page   500 502 503 504  /50x.html;
location = /50x.html {
    root html;
}   

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#   
location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
    # With php5-cgi alone:
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    include fastcgi_params;
}

Solution

  • 1 unless file exists will rewrite to index.php

    Add the following to your location ~ \.php$

    try_files = $uri @missing;
    

    this will first try to serve the file and if it's not found it will move to the @missing part. so also add the following to your config (outside the location block), this will redirect to your index page

    location @missing {
        rewrite ^ $scheme://$host/index.php permanent;
    }
    

    2 on the urls you never see the file extension (.php)

    to remove the php extension read the following: http://www.nullis.net/weblog/2011/05/nginx-rewrite-remove-file-extension/

    and the example configuration from the link:

    location / {
        set $page_to_view "/index.php";
        try_files $uri $uri/ @rewrites;
        root   /var/www/site;
        index  index.php index.html index.htm;
    }
    
    location ~ \.php$ {
        include /etc/nginx/fastcgi_params;
        fastcgi_pass  127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /var/www/site$page_to_view;
    }
    
    # rewrites
    location @rewrites {
        if ($uri ~* ^/([a-z]+)$) {
            set $page_to_view "/$1.php";
            rewrite ^/([a-z]+)$ /$1.php last;
        }
    }