Welcome! Log In Create A New Profile

Advanced

fastcgi_php.conf - resolve server environment compatibility with older PHP scripts

Posted by locojohn 
Hello all,

I decided to post my fastcgi_php.conf configuration file that helps me to resolve server environment compatibility issues with older PHP scripts that rely on PATH_INFO, PATH_TRANSLATED, SERVER_URL, SERVER_URI and PHP_SELF variables to be set correctly. Unfortunately, SCRIPT_NAME is not available, as if both SCRIPT_NAME and PHP_SELF are set in the FastCGI environment, PHP_SELF will eventually contain a concatenated string (a bug in PHP (F)CGI mode? - https://bugs.php.net/bug.php?id=55208)

I encourage everyone who has problems with older PHP scripts to test this if it works for them in their configuration.

fastcgi_php.conf:


# fastcgi_php.conf - configuration file for nginx that attempts to resolve
# server environment compatibility issues
# with older PHP scripts
#
# Author: Andrejs Eigus <aei(at)riga.ahlers.com> (c) 2011
#
#
# Example virtual host configuration:
#
# server ... {
#
# [...]
#
# location ~ ^(?<SCRIPT_FILENAME>.+\.php)(?<PATH_INFO>.*)$ {
# include fastcgi_php.conf;
# fastcgi_param PHP_VALUE "include_path=$document_root:$document_root/my/other/include/path";
# fastcgi_pass phpfarm;
# }
#
# [...]
#
# }
#

fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;

fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
# fastcgi_param DOCUMENT_URI $document_uri; # no script uses DOCUMENT_URI, as I know of
fastcgi_param SERVER_PROTOCOL $server_protocol;

fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;

fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;

fastcgi_param SCRIPT_FILENAME $document_root$SCRIPT_FILENAME;

fastcgi_param PATH_INFO $PATH_INFO;
fastcgi_param PATH_TRANSLATED $document_root$PATH_INFO;

fastcgi_param SCRIPT_URL $PATH_INFO;
fastcgi_param SCRIPT_URI $scheme://$http_host$PATH_INFO;

fastcgi_param PHP_SELF $uri;
# fastcgi_param SCRIPT_NAME $uri; # could not make it work if I set SCRIPT_NAME as well

# before fastcgi_pass, perform a little security check as to whether $SCRIPT_FILENAME actually exists

try_files $SCRIPT_FILENAME =404;

# fastcgi_pass ....


I will be happy to receive feedback

Andrejs
Hi Locojohn,

Thanks very much for this info - I had a real big problem over the weekend related to this, and, with a couple of changes, your script above helped me a lot. See http://forum.nginx.org/read.php?9,219565,219600#msg-219600 for how I did it.

Thanks again - very useful post.
Actually, there's more elegant way using the map directive:

On the http {} level you define:

map $uri $script_url {
~^(?<script_filename>.+\.(php|html))(?<path_info>.+)$ $path_info;
~^(?<script_filename>.+\.(php|html))$ $script_filename;
}

The above always sets $script_filename, $path_info and $script_url variables to appropriate values.

In the fastcgi_php.conf you define:

fastcgi_param CONTENT_LENGTH $content_length;

fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
# fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param SERVER_PROTOCOL $server_protocol;

fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;

fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;

fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;

fastcgi_param SCRIPT_URL $script_url;
fastcgi_param SCRIPT_URI $scheme://$http_host$script_url;

# fastcgi_param SCRIPT_FILENAME $document_root$script_filename;

# fastcgi_param PATH_INFO $path_info;
# fastcgi_param PATH_TRANSLATED $document_root$path_info;

try_files $fastcgi_script_name =404;


This should work.

Andrejs
If there was a like or +1 button for that, I'd have just clicked it! Thanks!
Thanks for putting this out, really helpful.

Using this configuration, when someone requests a non-existent PHP file they are redirected to the 404 page correctly, but the 404 error is not being logged in the error log file. I suspect it has something to do with:

try_files $fastcgi_script_name =404

I would think that we'd want PHP files that are not found to show up in the error log, is there a reason not to? is there an easy fix?
Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 77
Record Number of Users: 7 on March 06, 2014
Record Number of Guests: 184 on July 08, 2014
Powered by nginx    Powered by FreeBSD    PHP Powered    Powered by Percona     ipv6 ready