httpd.conf と .htaccess でリライト設定が異なる
.htaccess リライト設定をそのままApache設定ファイル(VirtualHostディレクティブ)に書いても動かずハマったのでメモ。
.htaccessに設定
RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php [QSA,L]
RewriteCond でリクエストファイルが存在するか判定します。
判定 | 実行される処理 |
---|---|
存在する | RewriteRuleを通らず直接リクエストファイルを表示 |
存在しない | RewriteRuleを通り index.php にリライトする |
よく見るリライト設定です。 説明の便宜上 .htaccess は example.jp のドキュメントルート直下に置いてあることにします。 ドキュメントルートは /var/www/html で /var/www/html/.htaccess にファイルがあるということになります。
VirtualHost ディレクティブに設定
同じように内容を VirtualHostディレクティブに設定します。 上と同じ動きになることを期待しますが、 「400 Bad Request」とエラーになってしまいます。
httpd.conf
<VirtualHost *:80> ServerName example.jp DocumentRoot /var/www/html RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php [QSA,L] </VirtualHost>
何が異なるのか?
リライトログを取って詳細の動きを追ってみました。 .htaccess と VirtualHostディレクティブ で異なる点は2点
REQUEST_FILENAME に入る値が違う
http://example.jp/hoge にアクセスすると
.htaccess → /var/www/html/hoge
VirtualHost → /hoge
VirtualHostの場合はドキュメントルート部分が抜けます。 正確に動かすには、 %{DOCUMENT_ROOT} 部分を追加する必要があります。
RewriteRule のリライト先に / が必要かどうか
.htaccess → RewriteRule のリライト先 index.php は .htaccess の置いてある階層の index.php と判定される。
VirtualHost → RewriteRule のリライト先 index.php は、ドキュメントルート直下にならずにエラーとなる
VirtualHost の場合は、/index.php と絶対指定に指定する必要があります。
上の2点を直すとこんな感じになります。 どうやら、VirtualHost 下に書くとドキュメントルートが基点にはならないようです。
httpd.conf
<VirtualHost *:80> ServerName example.jp DocumentRoot /var/www/html RewriteEngine On RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ /index.php [QSA,L] </VirtualHost>
ええぃ憶えるのめんどくさいぞぉ
こんなのすぐ忘れます。いつもApacheの設定をいじっている訳でもないですし。 曖昧な記憶から「あれっなんだたっけ」と思いだすオーバーヘッドも大きいです。
実は、Directoryディレクティブを使えば、.htaccess と同じ設定で書けます
こんな感じです。
httpd.conf
<VirtualHost *:80> ServerName example.jp DocumentRoot /var/www/html <Directory /var/www/html> RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php [QSA,L] </Directory> </VirtualHost>
Apacheのドキュメントにも、上の設定での、.htaccess と Directoryディレクティブは等価とあります。
ところで、ディレクティブの書かれた .htaccess を /www/htdocs/example に置くことと、同じディレクティブを 主サーバ設定の Directory セクション >
に書くことは 完全に等価です
Apache HTTP Server Tutorial: .htaccess files - Apache HTTP Server Version 2.4
Apache設定ファイルのリライト設定は、Directory [ドキュメントルート]に書く
と覚えておけば良いのではないでしょうか。これでコードを修正する手間などなくなります。