LaravelではどのURLを指定されても、(自分の担当するパス配下へのリクエストであれば)Laravel自身を起動させるために必ずpublic/index.phpを経由させる必要があります。
この設定はPHPだけでは限界があるため、Webサーバー側の設定で対応する必要があります。
Laravelのパッケージにはこの”index.phpを必ず経由させる”という設定が書かれた設定ファイルがデフォルトで含まれています。
具体的には
public/.htaccess
上記のファイルがこの設定ファイルにあたります。
ところが、この.htaccessファイルは基本的にApacheなどのごく一部のWebサーバーでしか認識しないので、たとえは先日の記事のようにnginxにPHPをインストールした環境で動作させようとしても、そのままではうまく動いてくれません。
この場合、.htaccessに書かれている設定と同様の働きになる設定をWebサーバーの設定ファイルに指定する必要が出てきます。
ただし、その記述の仕方もApacheとは異なってきますので、各Webサーバー用の書き方に書き換えないといけません。
nginxの場合、.htaccessの中身をnginx用の設定に書き換えてくれるWebサービスがあり、まず最初にこのサービスを使って変換した設定ファイルを使って設定を行ってみました。
元の.htaccess
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
上記サイトで変換後のnginxコンフィグ
# nginx configuration
location / {
if (!-e $request_filename){
rewrite ^(.*)$ /%1 redirect;
}
if (!-e $request_filename){
rewrite ^(.*)$ /index.php break;
}
}
実際に入れ込むと以下のようになります。
server {
listen 80;
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/ssl/fullchain.pem;
ssl_certificate_key /path/to/ssl/privkey.pem;
root /path/to/docroot;
client_max_body_size 1g;
location / {
if (!-e $request_filename){
rewrite ^(.*)$ /%1 redirect;
}
if (!-e $request_filename){
rewrite ^(.*)$ /index.php break;
}
index index.php index.htm index.html;
}
location ~ \.php$ {
if (!-e $request_filename){
rewrite ^(.*)$ /%1 redirect;
}
if (!-e $request_filename){
rewrite ^(.*)$ /index.php break;
}
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
allow all;
}
}
ところが、上記のような設定を行ったところ、リダイレクトループに陥ってしまいます。
いろいろ調べたところ、Nginx向けのLaravel用の設定が公開されていました。
nginxをLaravel5.4用に設定する – Qiita
上記の記事を基に今回の場合の設定ファイルを書き換えてみます。
server{
listen 80;
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/ssl/fullchain.pem;
ssl_certificate_key /path/to/ssl/privkey.pem;
root /path/to/docroot;
location / {
index index.php index.html index.htm;
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
全然違うじゃん…
やはり、ただ設定を変換しただけではうまく行かないみたいですね。
参考元の記事ではLaravel5.4となっていましたが、5.6の環境でも同様の設定で問題なく動作しました。
Laravel + Nginxの構築でお困りの方の参考になれば幸いです。