Nginx Redirect All Requests for Non-Existent Files to a Single PHP File

nginxPHPphp-fpmredirect

I have the following nginx vhost config:

server {
    listen 80 default_server;

    access_log /path/to/site/dir/logs/access.log;
    error_log /path/to/site/dir/logs/error.log;

    root /path/to/site/dir/webroot;
    index index.php index.html;

    try_files $uri /index.php;

    location ~ \.php$ {
            if (!-f $request_filename) {
                    return 404;
            }

            fastcgi_pass localhost:9000;
            fastcgi_param SCRIPT_FILENAME /path/to/site/dir/webroot$fastcgi_script_name;
            include /path/to/nginx/conf/fastcgi_params;
    }
}

I want to redirect all requests that don't match files which exist to index.php. This works fine for most URIs at the moment, for example:

example.com/asd
example.com/asd/123/1.txt

Neither of asd or asd/123/1.txt exist so they get redirected to index.php and that works fine. However, if I put in the url example.com/asd.php, it tries to look for asd.php and when it can't find it, it returns 404 instead of sending the request to index.php.

Is there a way to get asd.php to be also sent to index.php if asd.php doesn't exist?

Best Answer

Going by your additional comments this sounds like it might be the most optimal way, though it's not a pretty config.

server {
    listen 80 default_server;

    access_log /path/to/site/dir/logs/access.log;
    error_log /path/to/site/dir/logs/error.log;

    root /path/to/site/dir/webroot;
    index index.php index.html;

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

    location ~ \.php$ {
        try_files $uri @missing;

        fastcgi_pass localhost:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include /path/to/nginx/conf/fastcgi_params;
    }

    location @missing {
        rewrite ^ /error/404 break;

        fastcgi_pass localhost:9000;
        fastcgi_param SCRIPT_FILENAME $document_root/index.php;
        include /path/to/nginx/conf/fastcgi_params;
    }
}