変数の値に応じて別の変数を設定する(mapディレクティブ)
map ディレクティブは、ある変数の値に応じて別の変数の値を設定するためのディレクティブです。複数の条件分岐をまとめて定義できるため、設定ファイルを簡潔に記述することができます。ここでは Nginx における map ディレクティブの使い方について解説します。
mapディレクティブの書式
map ディレクティブは、指定した変数の値に応じて別の変数に設定する値をまとめて定義できるディレクティブです。 map ディレクティブの書式は次の通りです。
Syntax: map $source_variable $variable { ... }
Default: —
Context: http
map ディレクティブは http コンテキストで使用できます。引数として、一番目に基準となる変数を、二番目に値を設定する変数を指定します。そしてブロック内で基準の値に対して設定する値の対応表を記述します。
※ http コンテキスト内でのみ記述できる点に注意してください。
http {
map $基準の変数 $変数 {
基準値1 設定値1;
基準値2 設定値2;
基準値3 設定値3;
}
}
例えば基準の変数の値が「基準値1」だったら、変数に「設定値1」が設定されます。基準の変数の値が「基準値2」だったら、変数に「設定値2」が設定されます。(基準値と一致しているかどうか比較するときに、大文字小文字の区別は行いません)。
デフォルト値
default を使用すると基準の変数の値がブロック内のどの条件にも一致しなかった場合に変数に設定する値を指定できます。
http {
map $基準の変数 $変数 {
default デフォルト値;
基準値1 設定値1;
基準値2 設定値2;
}
}
default が設定されていなかった場合に、いずれの値とも一致しなかった場合、変数には空文字が設定されます。
正規表現の使用
基準値として正規表現を使用することもできます。大文字と小文字を区別する場合は、先頭に ~ を指定します。区別しない場合は先頭に ~* を指定します。
http {
map $基準の変数 $変数 {
基準値1 設定値1;
~正規表現パターン 設定値2;
~*正規表現パターン 設定値3;
}
}
ワイルドカードを使ったホスト名との比較
ブロックの先頭行に hostnames; と記述すると、基準の変数と比較する値としてホスト名を指定するときにワイルドカード(*)が使用できます。 hostnames を指定した場合、ホスト名として特別なルールでマッチが行われます。
http {
map $基準の変数 $変数 {
hostnames;
www.example.com 設定値1;
example.com 設定値2;
*.example.com 設定値3;
}
}
基準の変数として $host を使用する場合などに便利です。 *.example.comのように記述すると、すべてのサブドメイン(例えば www.example.com や blog.example.com)と一致します。また example.* と記述すると example.com や example.jp などに一致します。
また .example と記述すると example.com とそのすべてのサブドメインの両方に一致します。
複数の値に一致する場合の優先順位
正規表現を使っている場合など、基準の変数の値が複数の値と一致した場合、次の優先順位に従って変数に設定する値が決まります。
1. 文字列との一致(通常の値や example.comなど) 2. 先頭にワイルドカードが付いた文字列(*.example.com など) 3. 末尾にワイルドカードが付いた文字列(example.* など) 4. 最初にマッチした正規表現(設定ファイル内で上から順に評価されます) 5. デフォルト値
外部ファイルの利用
map ディレクティブの対応表が非常に大きくなる場合、設定内容を外部ファイルに分けて記述し、 map ディレクティブ内から include で読み込むことで、設定ファイルが読みやすくなります。
次の例を見てください。
http {
map $基準の変数 $変数 {
default デフォルト値;
基準値1 設定値1;
基準値2 設定値2;
基準値3 設定値3;
基準値4 設定値4;
基準値5 設定値5;
}
}
次のようなファイルを作成し、例えば c:/nginx/conf/map.confファイルとして保存します。
基準値1 設定値1; 基準値2 設定値2; 基準値3 設定値3; 基準値4 設定値4; 基準値5 設定値5;
※ 読み込むファイルには map ディレクティブ本体ではなく、対応表の内容のみを記述します。
作成したファイルを次のように include を使って読み込みます。
http {
map $基準の変数 $変数 {
default デフォルト値;
include c:/nginx/conf/map.conf;
}
}
map で定義している対応表が大きくなる場合は、このように外部ファイルに分けることで設定ファイルがすっきりします。
mapディレクティブの設定例
map ディレクティブの設定例をいくつか見ていきます。
http {
map $host $site_root {
hostnames;
example.com c:/nginx/html;
music.example.com c:/nginx/music;
blog.example.com c:/nginx/blog;
}
server {
location / {
root $site_root;
}
}
}
map ディレクティブを使い、リクエストのホストごとにルートディレクトリの値を設定しています。
組み込み変数 $host の値に応じて変数 $site_root にルートディレクトリのパスを表す文字列を設定しています。 location 内で root ディレクティブの値として $site_root を設定しています。
http {
map $request_uri $loggable {
default 1;
~*\.(css|js|png|jpg)$ 0;
}
access_log c:/nginx/logs/access.log combined if=$loggable;
}
map ディレクティブを使い、リクエストされた URI が CSS ファイル、 JS ファイル、画像ファイルだった場合はログを残さないように設定します。
組み込み変数 $request_uri の値の末尾が指定した拡張子だった場合に、変数 $loggable に 0 を設定し、それ以外の場合は 1 を設定しています。そして access_log 内で if オプションの値として $loggable を設定しています( 0 または空文字の場合はログを残さない)。
※ access_logディレクティブの詳しい使い方については、「アクセスログの出力設定(access_logディレクティブ)」を参照されてください。
http {
map $request_uri $new_uri {
default "";
/old/index1.html /new/index3.html;
/old/index5.html /new/index1.html;
~^/old/(.*) /new/$1;
}
server {
if ($new_uri) {
return 301 $new_uri;
}
}
}
map ディレクティブを使い、リダイレクトの設定をまとめて定義します。
組み込み変数 $request_uri の値に応じてリダイレクト先の URI を変数 $new_uri に設定しています。そして if 内で return ディレクティブを使って 変数 $new_uri に設定された URI へ 301 リダイレクトしています。(if ディレクティブで条件に変数を記述した場合、変数に設定された値が空文字または "0" 以外の場合に真となります。)。
動作確認
それでは実際に map ディレクティブの動作を確認してみます。 Nginx の設定ファイルである nginx.conf ファイルで http コンテキストに次のように設定しました。(必要な部分のみの抜粋です)。
http {
map $request_uri $new_uri {
default "";
/old/index1.html /new/index3.html;
/old/index5.html /new/index1.html;
~^/old/(.*) /new/$1;
}
server {
if ($new_uri) {
return 301 $new_uri;
}
}
}
map ディレクティブを使用して、リダイレクトの設定をまとめて定義しています。
ブラウザを起動し、次の URL へアクセスします。
http://localhost/old/index5.html
map ディレクティブで設定されたリダイレクト先である /new/index1.html へリダイレクトされます。
今度は次の URL へアクセスします。
http://localhost/old/index2.html
map ディレクティブで設定されたリダイレクト先である /new/index2.html へリダイレクトされます。
このように map ディレクティブを使用することで、条件に応じて変数の値を切り替える設定をまとめて記述できます。
-- --
Nginx における map ディレクティブの使い方について解説しました。
( Written by Tatsuo Ikura )
著者 / TATSUO IKURA
これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。