設定でハマったので備忘録を兼ねてメモ。
CodeIgniterを使うと、URLが以下のようになります。
http://host.com/index.php/class/function/ID
classはコントローラのクラス名、functionは実行するメソッド、IDはコントローラに渡されるID等です。
これだとindex.phpがURL的に目障りなので、
http://host.com/class/function/ID
こんな風にindex.phpを除去して使用します。
apacheだと設定例が豊富なのですが、nginxで見つかる設定例はどれもうまく動作しませんでした。
良く見る設定例はこんな感じのです。
location / {
index index.php index.html index.htm;
if (-f $request_filename) {
expires 30d;
break;
}
if (!-e $request_filename) {
rewrite ^(.+)$ /index.php?$1 last;
}
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
include /path/to/nginx/conf/fastcgi_params;
}
if (-f $request_filename)
の所で、実自在するファイルだったらそのまま処理するように指定して、
if (!-e $request_filename)
の所で、ファイルがなければ /index.phpをパスの頭に追加するようにしています。
後半のlocationではURI末尾が.phpの場合にphp-fpmにリクエストするように指定しています。
これだと、URIの末尾がphpではないCodeIgniterのURLは正しく処理できませんでした。
http://host.com/control1などでrewriteのログを見ると、
/control1 → /index.php/control1
/index.php/control1 → /index.php/index.php/control1
/index.php/index.php/control1 → /index.php/index.php/index.php/control1
:
とphpのクラス名がURLに含まれるため、見つかるはずのないファイルを探してループしてしまいます。rewriteは最大の10回で止まり、HTTP/500が戻されてしまいました。
URIの末尾に.phpがなくても、/index.phpから始まっているURIもphp-fpmで処理するようにします。
location ~ /index.php/(.*)$ {
root /usr/share/nginx/html;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
これを追加するとURIのrewriteと合わせてきちんと処理できるようになります。
http://host.com/control/function/IDだと、
/control/function/ID → /index.php/control/function/ID
/index.php/control/function/ID → php-fpmで処理
の流れです。
他にもtry_filesを使って
location / {
try_files $uri $uri/ /index.php;
}
こういうアプローチの設定も見かけますが、こちらは詳しく見ていません。
もしかしたら、こっちの方が良い方法なのかも。
locationとrewriteの設定をあれこれやってると、どんなふうに動作しているのかわからなくなって来ることがありますが、confファイルに以下のオプションを指定しておくと詳細なログが出力されて、問題の解決に役立ちます。
error_log /var/log/nginx/error.log debug;
rewrite_log on;
# highlight.jsってこういうコードだとダメなのね。。。
コメントする