mod rewriteの設定

mod rewriteは結構奥が深いです。通所のリダイレクト処理であるならばそれほどでもないのですが、深まれば底なしです。mod rewriteが通常のリダイレクトと違うのはApacheサイドの作業なのでURLを保持したままリダイレクトするということです。実際のファイルの階層構造では行ったり来たり、ジャンプしたり、端折ったり、無視したり…といろいろやっていますが、URL上では酷くクールに見えるというわけです。
mod rewriteの機能の特徴的な部分は、
あたかもマルチドメイン的な振る舞いをする。(あたかもではなく、そのままマルチドメインになるわけですが…)
動的なファイルをHTMLファイルなどに見せかけることができる。
ファイルやディレクトリ以外でもApacheのステータス(Not Found 403とか)を拾ってリダイレクトしたりできる。
というところでしょうか?入門編だったらここでまでで充分です。

マルチドメイン

あるホストに対して複数のドメインを向けるとその複数のドメインで同じホストサーバーを見ることができます。通常バーチャルドメインなどでも複数のドメインを単一のホストで処理することができますが、バーチャルホストではDocumentRootを指定してあげるという処理です。mod rewriteの場合はDocumentRootが同じでもそこからmod rewrite的なリダイレクトをかけて各ディレクトリにURLドメインを割り振ることができます。

www.example.com/ => /home/user/www/main/index.html
sub.example.com/ => /home/user/www/sub/index.html

こんな感じの設定です。
 通常/home/user/www/がDocumentRootだった場合は、単一のURLドメインでしか接続できません。しかしmod rewriteを使うと1階層したのディレクトリをあたかもDocumentRootのように見せかけることができるわけです。

RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.example.com$
RewriteRule ^$ /main/
RewriteCond %{HTTP_HOST} ^sub.example.com$
RewriteRule ^$ /sub/

どちらのURLも本来のDocumentRootにアクセスしてきます(/home/user/www/)。で、www.example.comアクセスしてきたものを/main/に放り込み、sub.example.comでアクセスしてきたものを/sub/以下に投げ込むというわけです。勿論これらのドメインがネームサーバーでもってこのホストに向けられていることが前提になりますが。
正規表現でのrewriteなので、^/$というようにスラッシュを入れても同じ意味(DocumentRootを指している)ということになると思いきや、エラーになりました。なんか難しいですね。

基本的なリダイレクト

あるディレクトリにアクセスした時にそのまま違うディレクトリへリダイレクトする時には、

RewriteEngine on
RewriteRule ^/hoge/$ /fuga/

と書きます。がいわゆるindex.htmlとかindex.phpにアクセスがあった時のみリダイレクトということになります。以下の階層も再帰的に丸ごととなると、

RewriteEngine on
RewriteRule ^/hoge/(.*)$ /fuga/$1

となります。この方法だと、ディレクトリの構造を保ったまま全部URLが書き換えられるので、端から見ればあたかも/fuga/にアクセスしているように見えます。URLが全く変わらないのに中身は全然違うところを指しているのがミソです。
また兄弟ディレクトリじゃなくても階層を上下してリダイレクトもできます。

RewriteEngine on
RewriteRule ^(.*)$ ../fuga/$1

カレントディレクトリにアクセスしてきたものを1階層上に上がってから別のディレクトリにアクセスしたりもできます。
 ここら辺りは自由に設定可能なので、よく使う設定例でいうとSSLの効いているディレクトリが別ディレクトリになっていてレンタルサーバーなんかで勝手に移動できないという時も便利です。

RewriteEngine on
RewriteRule ^/hoge/(.*)$ https://xxxxxxx/fuga/$1

hogeにアクセスしてきたものは、fugaに飛ばしつつhttps://でアクセスし直させることができます。

Last update: 2016.08.15 (月)