この例は、内蔵されたPHP FPM (FastCGI プロセスマネージャー)を使った新しいPHP (>= 5.3.3) のためのものです。
このガイドは、PHP FPMが既にインストールされていて、tcpポート (127.0.0.1:9000
) あるいはunixソケット (/var/run/php-fpm.sock
) のどちらかを使うように設定されていることを仮定します。
There are many guide about configuring NGINX with PHP FPM, but many of them are incomplete (don’t handle PATH_INFO correctly) or contain security issues (don’t check whether the script is indeed php file).
まず、全ての代表的なFCGI設定を1つのファイルにまとめ、それらをimportすることをお勧めします。
For example on debian and ubuntu by default there is /etc/nginx/fastcgi_params
file that should look like this:
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 SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
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;
fastcgi_param HTTPS $https;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
Ubuntu Precise (12.04) を使っている場合、SCRIPT_FILENAME
を変更し、PATH_INFO
パラメータを追加することに注意してください。
ここで、NGINXがFCGIプロトコルを使ってリクエストをPHP FPMにproxyするように指示しなければなりません:
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
# Mitigate https://httpoxy.org/ vulnerabilities
fastcgi_param HTTP_PROXY "";
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
}
unixソケットを使っている場合は、fastcgi_pass
を以下に変更してください:
fastcgi_pass unix:/var/run/php5-fpm.sock;
NGINXを再起動します。
ちょうど以下のものを含むtest.php
をNGINXドキュメントルート上に作成します:
var_export($_SERVER)?>
ブラウザ内で以下をリクエストしてみてください: # /test.php # /test.php/ # /test.php/foo # /test.php/foo/bar.php # /test.php/foo/bar.php?v=1
REQUEST_URI, SCRIPT_NAME, PATH_INFO および PHP_SELF の値に注意してください。
以下はhttp://lemp.test/test.php/foo/bar.php?v=1の正しい出力です
array (
'USER' => 'www-data',
'HOME' => '/var/www',
'FCGI_ROLE' => 'RESPONDER',
'QUERY_STRING' => 'v=1',
'REQUEST_METHOD' => 'GET',
'CONTENT_TYPE' => '',
'CONTENT_LENGTH' => '',
'SCRIPT_FILENAME' => '/var/www/test.php',
'SCRIPT_NAME' => '/test.php',
'PATH_INFO' => '/foo/bar.php',
'REQUEST_URI' => '/test.php/foo/bar.php?v=1',
'DOCUMENT_URI' => '/test.php/foo/bar.php',
'DOCUMENT_ROOT' => '/var/www',
'SERVER_PROTOCOL' => 'HTTP/1.1',
'GATEWAY_INTERFACE' => 'CGI/1.1',
'SERVER_SOFTWARE' => 'nginx/1.4.0',
'REMOTE_ADDR' => '192.168.56.1',
'REMOTE_PORT' => '44644',
'SERVER_ADDR' => '192.168.56.3',
'SERVER_PORT' => '80',
'SERVER_NAME' => '',
'HTTPS' => '',
'REDIRECT_STATUS' => '200',
'HTTP_HOST' => 'lemp.test',
'HTTP_USER_AGENT' => 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:20.0) Gecko/20100101 Firefox/20.0',
'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'HTTP_ACCEPT_LANGUAGE' => 'en-US,en;q=0.5',
'HTTP_ACCEPT_ENCODING' => 'gzip, deflate',
'HTTP_CONNECTION' => 'keep-alive',
'PHP_SELF' => '/test.php/foo/bar.php',
'REQUEST_TIME' => 1367829847,
)
PATH_INFO
and properly check that the extension indeed .php (not .phps) whether there is PATH_INFO or not.fastcgi_split_path_info
regex capable to correctly handle request like /test.php/foo/blah.php
or /test.php/
.if
lets NGINX check whether the *.php
does indeed exist to prevent NGINX to feeding PHP FPM non php script file (like uploaded image).Some guides recommend to use try_files
instead of if
,
if you do that, beware of NGINX bug #321.
I personally think if
is more appropriate for this, even If Is Evil agree this is one of the 100% safe thing to use if
with.
このガイドはphp.ini 上のcgi.fix_pathinfo = 1
(デフォルト)で良く動作します。幾つかのガイドはそれをcgi.fix_pathinfo = 0
に変更するように言い張りますが、そうするとPHP_SELF
変数を破壊します(DOCUMENT_URI
と同じではありません)。