WordPressのmod_rewriteコードを参考にmod_rewriteについてまとめてみました。
mod_rewriteとは?
mod_rewriteとは、何かご存知でしょうか?
これは、Apacheというhttpサーバで利用されいてるモジュールと言われるもので、URLの書き換え・リダイレクト処理を行なってくれるものです。
主に「.htaccess」というファイルに任意の処理を記述して使用します。
mod_rewriteですが、使ってはいるけど内容はよくわからない方も多いのでは無いでしょうか?
実際にWordPressのパーマリンク設定で利用しているmod_rewrite のコードを参考に説明を行なっていきます。
まずは、利用しているコードを確認してみましょう。
WordPressのパーマリンク設定で利用しているmod_rewrite
1 | <IfModule mod_rewrite.c> |
2 | RewriteEngine On |
3 | RewriteBase / |
4 | RewriteCond %{REQUEST_FILENAME} !-f |
5 | RewriteCond %{REQUEST_FILENAME} !-d |
6 | RewriteRule . /index.php [L] |
7 | </IfModule> |
WordPressのサイトを運用している方は、ほとんどの方が見たことがあるのではないかと思うくらいおなじみのやつですね。
実際にWordPressを運用している方でも、この記述を理解している方は半分くらいじゃないかと個人的に予想しています。
私も、はじめの内は全くわからずに利用をしておりました。
WordPressを初めて利用した際に当時WEBの初心者であった私は、とても驚きました。
どうして、このコードを記載するだけでパーマリンクを自由に設定ができるのか。
どうして、ピンポイントに存在しないファイルだけ静的なファイルが読み込まれるのか。
どうして、存在しないページでもちゃんとWordPressのエラーページが表示されるのか。
そのカラクリが不思議で仕方がありませんでした。
今回WordPressを選択した理由は、私と同様に不思議に感じていた方もいるのでは無いかという事と、様々な記述がありステップアップにも調度良いという事。WordPress自体が広く普及している点があります。
一行目から順にどういった意味を持つコードなのか確認していきましょう。
1 | <IfModule mod_rewrite.c> |
何やらHTMLタグのような形で記述されていますね。
最後の行も見てみると、今度はHTMLの閉じタグのような形で記載されています。
これは利用環境でmod_rewriteが利用できるかどうかを確認しています。
もし利用できない場合は、このHTMLタグのような形で挟まれている行のコードが一切適用されなくなります。
mod_rewriteが利用できない環境でmod_ rewriteのコードを記述するとエラーが発生してしまいます。ですから、このようにモジュールが利用できるか確認を行なってから実行してくださいという記述をします。
1 | RewriteEngine On |
これはmod_rewriteの機能を有効化するという記述になります。
Offと記述すれば無効化します。非常に簡単です。
1 | RewriteBase / |
これはRewrite処理後にベースとなるURLの指定しています。
この記述がない場合は、htaccessを設置しているディレクトリが自動的に選択されますが、これは後述するRewriteRuleを相対パスで記述した場合にのみ適用されます。
特に理由がない場合は、「RewriteBase /」と記述しておく事をオススメします。
この場合だと、どのディレクトリに設置を行った場合でも必ずドキュメントルートからのパスになりますので、わかりやすくなります。
1 | RewriteCond %{REQUEST_FILENAME} !-f |
ここから、いよいよRewrite処理を記述している部分となります。
RewriteCondではルールの定義を行っています。
Rewrite処理を設定する上で欠かせないポイントなので、mod_rewriteを使う上で特に重要です。
普段、プログラムを普段やられている方はmod_rewriteで使用するif文だと思って貰えればイメージがしやすいと思います。
RewriteCondの次に記述されいている部分「%{REQUEST_FILENAME}」というものが、「!-f」という条件を満たしていれば真となります。
if文で記述してみると下記の様になります。
1 | if(%{REQUEST_FILENAME} != -f) |
2 | { |
3 | 真 |
4 | } |
まず前方の%{REQUEST_FILENAME}から確認して行きます。
これは変数です。この変数というものには、自分で好きな文字列を入れるものと、サーバーが事前に準備を行なってくれる環境変数というものがあります。
今回使用されているREQUEST_FILENAMEとは環境変数と呼ばれる変数の一部で、このREQUEST_FILENAME以外にも様々なものがあります。
例えばですが、SSL通信かどうかを判断するために利用されるHTTPSや、特定のIPアドレスからアクセスされた場合に参照先を変更するために利用するREMOTE_ADDR等があります。
今回は2つのみ挙げさせて頂きましたが、これ以外にもたくさんの環境変数が存在します。
環境変数の一例
環境変数名 | 内容 |
---|---|
HTTP_USER_AGENT | ユーザのブラウザや端末情報を取得することができます。 携帯サイトやスマホサイトなどへの振分の際に利用されます。 |
HTTP_REFERER | 前にいたページのURL情報を取得出来ます。 特定のページからの導線のみ許可したい場合などに利用します。 |
HTTP_HOST | 閲覧しているサイトのドメインです。 主にRewriteRuleなどに使用します。 |
REMOTE_ADDR | ユーザのIPアドレスの取得を行います。 特定のIPのみに特別な処理をしたい場合などに使用します。 |
HTTPS | on|offでSSL通信の有無を判定できます。 |
SERVER_PORT | HTTPSが上手く利用できない場合などに使用します。 |
このような変数を利用して、様々なルールを作ることができます。
PHPが利用できるサーバーであれば、var_dump($_SERVER)やphpinfo()という関数を利用して環境変数にどのような値が変数に入っているのか確認も可能です。
次に後方部分の!-fについてですが、こちらは条件の記述です。
!-fには2つの条件が含まれており、「!」と「-f」に分割することが出来ます。
まず「-f」はモジュールで準備をしてくれている判定ルールです。これは、前方に指定されていた変数、今回の場合は%{REQUEST_FILENAME}に入っている物がファイルであるかどうかを判定してくれます。
ファイルの場合は、真。ファイル以外の場合は、偽を返します。
分割されたもう一つの「!」は否定です。
結果を逆転させるもので、真と判定されたものは偽となり、偽と判定されたものは真となります。ですから今回の「!-f」の場合はファイル以外の場合は、真を。ファイルの場合は偽を返します。
1 | RewriteCond %{REQUEST_FILENAME} !-d |
また先ほどと同じような記述がされていますが、条件の部分のみ変更されています。
「-d」と記述されていますが、これはディレクトリかどうかの検証を行います。
%{REQUEST_FILENAME}がディレクトリの場合は真を、それ以外の場合は偽を返しますが、先ほどと同様に「!」がついていますので、結果は逆になります。
RewriteCondが2回続きました。
このように複数回RewriteCondが続いた場合は、全てのRewriteCondで真となる必要があります。偽が1つでもあるとRewrite処理の対象から外れてしまいます。
また、「-d」「-f」などモジュールで準備されている判定ルールですが、もちろんこの2つ以外にもいつくかあります。ただ、利用される部分も少ないため今回の説明を割愛させて頂きます。
1 | RewriteRule . /index.php [L] |
これは実際にURLの書き換えを行う部分です。
上記はURLが「.(ドット)」であれば「/index.php」を参照するという命令です。
「.(ドット)」の部分が条件となり、ドットはどのような条件でも適用するという条件になります。
「/index.php」はどのように書き換えを行うか記述しており、今回は/index.phpに書き換えを行なっています。
したがって今回の場合は、「すべてのリクエストは/index.phpに書き換えられる」ということになります。
そして記述に一番最後に「[L]」という記述がありますが、これはLastという意味で「このルールが適用されたら、この記述以降の他のルールは適用しません。」という命令です。
これはフラグと言われるもので、RewriteCondにも利用できますし、フラグ自体もL以外にもたくさんあります。
その中でもよく使うものをご紹介します。
[NC]:no case:大文字と小文字を区別しなくなります。
1 | RewriteCond %{HTTP_REFERER} example.com [NC] |
この場合は、%{HTTP_REFERER}が「Example.com」でも「EXAMPLE.COM」でも真となります。
[R]:redirect:これは書き換え後のURLにリダイレクトを行うことができます。
R=301等の記述をすることでリダイレクトパラメータを使用することもできます。
1 | RewriteCond %{HTTP_HOST} ^example\.com |
2 | RewriteRule (.*) http://www.example.com/$1 [R=301,L] |
というような記述をすると、www付きのアドレスにリダイレクトパラメータ付きでリダイレクトさせることが可能です。
また上記のサンプルコードのように[R=301,L]と,(カンマ)で区切ることにより複数のフラグを設定することも可能です。
このリダイレクトの記述がない場合は、リダイレクトは行わず内部的にURLの書き換えだけを行うことになります。
以上が、WordPressで利用しているmod_rewriteの全てです。
改めてコードを見なおしてみましょう。
1 | <IfModule mod_rewrite.c> |
2 | RewriteEngine On |
3 | RewriteBase / |
4 | RewriteCond %{REQUEST_FILENAME} !-f |
5 | RewriteCond %{REQUEST_FILENAME} !-d |
6 | RewriteRule . /index.php [L] |
7 | </IfModule> |
この内容は、
- mod_rewriteモジュールを使用出来る。
- ファイルが存在しない。
- ディレクトリが存在しない。
という上記にあるすべての条件に当てはまるリクエストは、すべて「/index.php」を参照して下さい。
ということになります。
見た目はよくわからない英語の文字列が記述されていますので、難しく感じてしまいますが日本語に直してみると、わかりやすいのではないでしょうか。
Tips
上記は必ず大文字から記述されていますが、特にこのような記述にしなければいけないルールはありません。もちろん、ルール設定の際には重要になりますがその他の点に関しては、「rewriteengine on」という様に記述した場合でも、問題なく動作します。ただ、可読性や統一をするという意味でもドキュメントに則った記述を行うことをオススメします。
◆参考サイト
http://rfs.jp/server/apache/02apache/url_rewrite.html
http://net-newbie.com/trans/mod_rewrite.html#RewriteBase
http://p.tl/oV_J
http://httpd.apache.org/docs/current/ja/mod/mod_rewrite.html