Nginx: Map single static URL to a PHP file

fastcginginx

I have a WordPress installation up and running without issue. There is an element on the page that is not part of WP, but our own custom PHP script. It's just there to handle form POST requests and process it in someway.

There is a requirement that we don't have extensions that end in .php. My form is submitting to something like:

/places/signup.html

In my nginx config, I have this:

server {
    listen       87948; # It's behind a reverse proxy
    server_name domain.com www.domain.com;

    include /etc/nginx/proxy_params;

    index index.php;
    root /opt/www/public_html;

    location /favicon.ico {
        return 404;
    }

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

    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires max;
        log_not_found off;
    }

    location ~ \.php$ {
        add_header Access-Control-Allow-Origin "*";
        client_body_buffer_size 4096k;
        fastcgi_pass unix:/tmp/php5-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /opt/www/public_html/$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_script_name;
        include /etc/nginx/fastcgi_params;
    }

    # LOOK HERE
    location ~ /places/signup.html {
        root                             /opt/www/custom_scripts/;
        fastcgi_pass    unix:/tmp/php5-fpm.sock;
        fastcgi_param   SCRIPT_FILENAME  /opt/www/custom_scripts/signup-processor.php;
        fastcgi_param   QUERY_STRING     $query_string;
        fastcgi_param   REQUEST_METHOD   $request_method;
        fastcgi_param   CONTENT_TYPE     $content_type;
        fastcgi_param   CONTENT_LENGTH   $content_length;
        include         fastcgi_params;
    }

}

The problem is: fastcgi or nginx (I have no idea which) is taking the literal URL and looking for it in the location block's root directive. From the error log:

2013/01/16 15:30:42 [error] 20533#0: *4 FastCGI sent in stderr:
"Unable to open primary script:
/opt/www/custom_scripts/places/signup.html (No such file or
directory)" while reading response header from upstream, client:
66.172.31.153, server: domain.com, request: "POST /places/signup.html HTTP/1.1", upstream: "fastcgi://unix:/tmp/php5-fpm.sock:", host:
"www.domain.com"

I thought "fastcgi_param SCRIPT_FILENAME /opt/www/custom_scripts/signup-processor.php;" would force it to use that specific script? I guess not?

Best Answer

The include directive at the end :

    include         fastcgi_params;

probably has another fastcgi_param directive with a SCRIPT_FILENAME parameter :

    fastcgi_param   SCRIPT_FILENAME  /another/script/file/name;

As it's at the end of the file, it will override your value.

If you want to keep some settings from your fastcgi_params file, but override them with specific ones, you should place the include directive at the beginning :

location ~ /places/signup.html {
    include         fastcgi_params;
    root                             /opt/www/custom_scripts/;
    fastcgi_pass    unix:/tmp/php5-fpm.sock;
    fastcgi_param   SCRIPT_FILENAME  /opt/www/custom_scripts/signup-processor.php;
    fastcgi_param   QUERY_STRING     $query_string;
    fastcgi_param   REQUEST_METHOD   $request_method;
    fastcgi_param   CONTENT_TYPE     $content_type;
    fastcgi_param   CONTENT_LENGTH   $content_length;
}
Related Topic