nginx fastcgi_params を include する箇所、割と皆間違ってるよね？


## `fastcgi_param` ディレイクティブについて

[Module ngx_http_fastcgi_module](http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_param "Module ngx_http_fastcgi_module")

> ```
> Syntax:	fastcgi_param parameter value [if_not_empty];
> Default:	—
> Context:	http, server, location
> ```
> Sets a parameter that should be passed to the FastCGI server. The value can contain text, variables, and their combination. These directives are inherited from the previous level if and only if there are no fastcgi_param directives defined on the current level.

FastCGI サーバに渡されるべきパラメータを設定します。 値にはテキスト、 変数、それらの組み合わせを含むことができます。現在のレベルに `fastcgi_param` ディレクティブが無い場合に限り、これらのディレクティブは上のレベルから引き継がれます。

nginx のドキュメントルートに下記のコードを含んだ PHP ファイルを作成することで、パラメータの設定値を確認できます。

```php
<?php var_export($_SERVER); ?>
```

## よく見かける誤りがある FastCGI の設定

下記の設定では、 `SCRIPT_FILENAME` のパラメータは `$document_root$fastcgi_script_name` ではなく `$request_filename` が設定されてしまい、 `fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;` の記述は無意味となります。
理由としては、 `fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;` より後に `include fastcgi_params;` と記述されているため、
`/etc/nginx/fastcgi_params` ファイル内の `fastcgi_param SCRIPT_FILENAME $request_filename;` が有効となり上書きされてしまうからです。

※ `PATH_INFO` `PATH_TRANSLATED` に関しては、 `/etc/nginx/fastcgi_params` ファイル内で設定されていないため `include fastcgi_params;` の前後関わらず期待通りのパラメータが設定されます。

```nginx:/etc/nginx/nginx.conf
location ~ [^/]\.php(/|$) {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    if (!-f $document_root$fastcgi_script_name) {
        return 404;
    }
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.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;
    include fastcgi_params;
}
```

`/etc/nginx/fastcgi_params` で設定されたパラメータを上書きしたい場合は、 `include fastcgi_params;` より後でパラメータを設定する必要があります。

## 正しい FastCGI の設定

以下のような 2 通りの設定があります。

### `/etc/nginx/fastcgi_params` を include した後でパラメーターを設定する

```nginx:/etc/nginx/nginx.conf
location ~ [^/]\.php(/|$) {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    if (!-f $document_root$fastcgi_script_name) {
        return 404;
    }
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
    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;
}
```

### `/etc/nginx/fastcgi_params` を編集し include する

```diff:/etc/nginx/fastcgi_params
	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         $request_filename;
+	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;
```

```nginx:/etc/nginx/nginx.conf
location ~ [^/]\.php(/|$) {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    if (!-f $document_root$fastcgi_script_name) {
        return 404;
    }
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
}
```