.htaccessはディレクトリ単位でApacheの設定ができて便利ですが、セキュリティやパフォーマンスを重視する場合には.htaccessを使用しないこともあります。
.htaccessを利用できない環境下でLaravelを使うには、Apacheをどのように設定すればよいか、解説します。
Laravelの.htaccess
まず、Laravelの.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]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
.htaccessには、いろいろ書かれていますが、結局やっていることは3つです。
- 環境変数HTTP_AUTHORIZATIONを設定(FastCGI用)
- / で終わるURLを、/ がないURLへリダイレクト
- 静的ファイル以外、index.php で処理させる
.htaccessに書かれたこれらの内容をhttpd.confに移動して、動作させてみます。
httpd.confの<Directory>ディレクティブで設定する
.htaccessの内容を<Directory>ディレクティブ内に記述する方法がもっとも簡単です。
httpd.confには、次のように記述します。
<Directory /var/www/laravel/>
Require all granted
AllowOverride none
# Laravelの設定はここから
<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]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /index.php [L]
</IfModule>
</Directory>
httpd.confの<VirtualHost>内でLaravelを設定する
<Directory>ディレクティブではなく、<Location>や<VirtualHost>内で設定することもできます。
httpd.confには、次のように記述します。
<VirtualHost *:80>
ServerName example.com
# Laravelの設定はここから
Options -MultiViews -Indexes
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond /var/www/laravel/public%{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Send Requests To Front Controller...
RewriteCond /var/www/laravel/public%{REQUEST_FILENAME} !-d
RewriteCond /var/www/laravel/public%{REQUEST_FILENAME} !-f
RewriteRule ^ /index.php [L]
</VirtualHost>
.htaccessと記述を変更したのは、以下の2か所です。
%{REQUEST_FILENAME}
の前にLaravelディレクトリを追加- リライトルールの最終URLを index.php から /index.php に変更
%{REQUEST_FILENAME}の前にLaravelディレクトリを追加
.htaccessで設定した内容を、httpd.confなどのサーバーレベルのファイルに設定を移動すると、そのまま動く場合もありますが、パスやディレクトリに関連した動作が変更されてしまいます。
RewriteCond
ディレクティブで使っている変数 %{REQUEST_FILENAME}
もそのうちの一つで、.htaccessに記述した時と、httpd.confに記述したときとでは動作が異なります。
変数名 | .htaccessで記述した時 | httpd.confで記述した時の値 |
---|---|---|
REQUEST_FILENAME | ファイルの絶対パス (例)/var/www/html/foo.html | リクエストURI (例)/foo.html |
そのため、%{REQUEST_FILENAME}
の直前に /var/www/laravel/public というLaravelのドキュメントルートを指定しています。
最後のRewriteRuleを/index.phpに変更
Laravelの.htaccessでは、最終的にリクエストをindex.phpで処理させるようにURLをリライトしています。
また、RewriteRuleではリライト先URLを index.php と、同一ディレクトリ内のindex.phpで処理させるように指定しています。
RewriteRule ^ index.php [L]
ただし、この記述をサーバーレベルの設定ファイルに持っていくと、400 Bad Requestエラーとなってしまいます。
なぜなら、サーバーレベルの設定ファイルでは、リクエストURIがリライト対象となりますが、リライト後のURLが/から始まらないURIになるためです。
そこで、リライト後のURLは /index.php のように指定します。
RewriteRule ^ /index.php [L]
どのディレクティブ内に移動するかによって設定変更が必要
以上、Laravelの.htaccessをhttpd.confに移動する方法を紹介しました。
注意が必要なのが、設定する場所に応じて内容を変更する必要がある点です。設定の違いに着目すれば、難なく正しく動作させることができます。
WordPressの.htaccessも同じ方法で移動できるはずなので、やってみてください。