前書き
ファイルが存在するかどうかの記述でよく、 if (-f $request_filename) { ... }
と if (-f $document_root$fastcgi_script_name) { ... }
の2通りがあるが、これって何か違うの?って思った時がありました。
その頃、調べた内容を下記に記します。
変数の意味
$request_filename
Module ngx_http_core_module #variables
現在のリクエストのファイルパスは、 root
または alias
ディレクティブとリクエストの URI に基づきます。
$document_root
Module ngx_http_core_module #variables
現在のリクエストの root
または alias
ディレクティブの値です。
$fastcgi_script_name
Module ngx_http_fastcgi_module #variables
URI がスラッシュで終わっている場合、URI をリクエストするか、 URI に fastcgi_index
ディレクティブによって設定されたインデックスファイル名をつけてリクエストしてください。この変数は、 PHPのスクリプト名を決定する SCRIPT_FILENAME
と PATH_TRANSLATED
パラメータを設定するために使用することができます。例えば、次のディレクティブを持つ /info/
リクエストについて
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/www/scripts/php$fastcgi_script_name;
SCRIPT_FILENAME
パラメータは /home/www/scripts/php/info/index.php
と等しい。
fastcgi_split_path_info
ディレイクティブを使っている場合、 $fastcgi_script_name
はそのディレイクティブにより設定された一つ目のキャプチャの値と等しい。
※ 正規表現では、特定のパターンにマッチした文字列を後で参照できるように保存しておくことをキャプチャと呼びます。
上記の変数を扱う上で押さえておくべき重要なディレイクティブ
fastcgi_split_path_info
ディレイクティブ
Module ngx_http_fastcgi_module #fastcgi_split_path_info
Syntax: fastcgi_split_path_info regex;
Default: —
Context: location
$fastcgi_path_info
の値をキャプチャする正規表現を定義します。正規表現は、2つのキャプチャを持つ必要があります。一つ目は $fastcgi_script_name
の値になり、二つ目は $fastcgi_path_info
の値になります。例えば、以下のようなの設定の場合
location ~ ^(.+\.php)(.*)$ {
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param SCRIPT_FILENAME /path/to/php$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
そして、 /show.php/article/0001
リクエストは、SCRIPT_FILENAME パラメータは /path/to/php/show.php
と等しく、 PATH_INFO
パラメータは /article/0001
と等しい。
fastcgi_index
ディレイクティブ
Module ngx_http_fastcgi_module #fastcgi_index
Syntax: fastcgi_index name;
Default: —
Context: http, server, location
$fastcgi_script_name
の値で、スラッシュで終わる URI の後に追加されるファイル名を設定します。例えば、以下のような設定の場合
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/www/scripts/php$fastcgi_script_name;
そして、 /page.php
リクエストは、SCRIPT_FILENAME パラメータは /home/www/scripts/php/page.php
と等しく、 /
とリクエストされた場合は /home/www/scripts/php/index.php
と等しい。
本題
結局違いは?
下記の記事を見つけました。
web server - Nginx $document_root$fastcgi_script_name vs $request_filename - Server Fault
You get the request "/info/" and have the following configuration:
fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /home/www/scripts/php$fastcgi_script_name;
SCRIPT_FILENAME would equal "/home/www/scripts/php/info/index.php", but using $request_filename it would just be "/home/www/scripts/php/info/".
/info/
とリクエストされ、 SCRIPT_FILENAME
パラメータに /home/www/scripts/php$fastcgi_script_name
を使用した場合 /home/www/scripts/php/info/index.php
と等しいが、 $request_filename
を使用した場合は /home/www/scripts/php/info/
と等しい。
とのことでした。上記の記述が正しいかどうか実証してみます。
実証
前提
下記の記事内容を最低限把握している程で実証をするため、インストール手順や公開ディレクトリの作成、設定後の再起動等は省略します。
nginx と php-fpm の仕組みをちゃんと理解しながら PHP の実行環境を構築する - Qiita
環境
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.1 LTS"
設定
add_header
ディレイクティブを使って変数の確認を行います。詳しく知りたい方は下記をご覧ください。
nginx 変数の値を確認したい時は add_header ディレイクティブを使うと超絶簡単 - Qiita
server {
listen 80 default_server;
root /home/www/scripts/php;
index index.php index.html index.htm;
server_name localhost;
location /info/ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
add_header $request_filename $request_filename;
add_header $document_root$fastcgi_script_name $document_root$fastcgi_script_name;
}
}
変数の値を確認
/info/
でリクエスト
$ curl -I localhost/info/
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Mon, 28 Mar 2016 11:30:28 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
$request_filename: /var/www/info/
$document_root$fastcgi_script_name: /var/www/info/index.php
/info/index.php
でリクエスト
$ curl -I localhost/info/index.php
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Mon, 28 Mar 2016 11:30:13 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
$request_filename: /var/www/info/index.php
$document_root$fastcgi_script_name: /var/www/info/index.php