本日はapacheのmod_rewriteについて。
例えばget句に郵便番号を付けて、住所を出力するWEBプログラムがあるとします。
この場合、そのままだと http://sampledomain.com/sampleapp/public/address.php?zip=1048404 ですが、こういったURLを http://sampledomain.com/sampleapp/public/address/1048404 でアクセスしたいとします。
こんな時に必要になるのが http://sampledomain.com/sampleapp/public/address/1048404 でアクセスし、内部で http://sampledomain.com/sampleapp/public/address.php?zip=1048404 と書き換える機能です。
これはapacheのmod_rewriteというモジュールで行います。
Apache2.4系を前提に説明します。(検索するとこれ以前のものが多く出てきますんで逆に2.4以前のものの情報には困らないかと思います。)
一応過去のブログを参考リンクに。
サーバー設定ファイルについて apache
mod_rewrite
/etc/httpd/conf.modules.d/00-base.conf
ここに下記のようにモジュールが組み込まれていればOKです。
1 |
LoadModule rewrite_module modules/mod_rewrite.so |
あとはphpinfoで見て、Loaded Modulesのなかにmod_rewriteが書かれていればOKです。
デバッグ
URLのrewriteの場合、プログラムと違って中がどうなっているのかを把握するのが難しいので情報をログから取るしかありません。ログへの出力の抑制などは下記を/etc/httpd/conf/httpd.confにかいてあげればOKです。
1 |
LogLevel debug rewrite:trace8 |
※注意点としては先ほどのmodule読み込みよりも後に書かないと反映されません。
またどのくらいの情報を出力できるかをコントロールできます。出力レベルはdebug~emergeまであります。具体的には下記を参照
http://httpd.apache.org/docs/2.4/ja/mod/core.html#loglevel
またrewriteの情報も出力レベルが1~8まであり、数字が大きいほど詳しいです。
ログのパスなどは2.4系では自動的にapacheのerror_logに吐かれます。また具体的なURLのrewriteはアプリのディレクトリ直下に.htaccessをおいてこれで管理することがほとんどですので、.htaccessが機能するようにしておきましょう。
.htaccess
具体的なrewriteなどはアプリのディレクトリ直下のhtaccessに記述することが多いです。
今回のケースの場合、 /var/www/html/sampleapp/public/address.php にプログラムがあるとすると、htaccessのパスは /var/www/html/sampleapp/.htaccess になります。
ここで下記のように記述します。
1 2 3 4 5 6 |
<IfModule mod_rewrite.c> #mod_rewriteがあればという意味 #ここでrewriteをOnにします。 RewriteEngine On #下記でリダイレクトをします。 RewriteRule public/address/(\d+) public/address\.php?zip=$1 </IfModule> |
具体的なrewriteのルールを知りたい場合は以前も紹介しましたが、下記のリンクが詳しいです。
Apacheのmod_rewriteモジュールの使い方を徹底的に解説
ログには具体的に下記のようにリダイレクトが吐かれます。リダイレクトがうまくいっていないときはここで一回一回確認しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[Wed May 31 18:51:48.958462 2017] [rewrite:trace3] [pid 5478] mod_rewrite.c(470): [client 192.168.1.29:55447] 192.168.1.29 - - [192.168.1.28/sid#7f4d6d652310][rid#7f4d6da4bdc0/initial] [perdir /var/www/html/sampleapp/] add path info postfix: /var/www/html/sampleapp/public/address -> /var/www/html/sampleapp/public/address/1010051 [Wed May 31 18:51:48.958475 2017] [rewrite:trace3] [pid 5478] mod_rewrite.c(470): [client 192.168.1.29:55447] 192.168.1.29 - - [192.168.1.28/sid#7f4d6d652310][rid#7f4d6da4bdc0/initial] [perdir /var/www/html/sampleapp/] strip per-dir prefix: /var/www/html/sampleapp/public/address/1010051 -> public/address/1010051 [Wed May 31 18:51:48.958484 2017] [rewrite:trace3] [pid 5478] mod_rewrite.c(470): [client 192.168.1.29:55447] 192.168.1.29 - - [192.168.1.28/sid#7f4d6d652310][rid#7f4d6da4bdc0/initial] [perdir /var/www/html/sampleapp/] applying pattern 'public/address/(\\d+)' to uri 'public/address/1010051' [Wed May 31 18:51:48.958501 2017] [rewrite:trace2] [pid 5478] mod_rewrite.c(470): [client 192.168.1.29:55447] 192.168.1.29 - - [192.168.1.28/sid#7f4d6d652310][rid#7f4d6da4bdc0/initial] [perdir /var/www/html/sampleapp/] rewrite 'public/address/1010051' -> 'public/address.php?zip=1010051' [Wed May 31 18:51:48.958511 2017] [rewrite:trace3] [pid 5478] mod_rewrite.c(470): [client 192.168.1.29:55447] 192.168.1.29 - - [192.168.1.28/sid#7f4d6d652310][rid#7f4d6da4bdc0/initial] split uri=public/address.php?zip=1010051 -> uri=public/address.php, args=zip=1010051 [Wed May 31 18:51:48.958519 2017] [rewrite:trace3] [pid 5478] mod_rewrite.c(470): [client 192.168.1.29:55447] 192.168.1.29 - - [192.168.1.28/sid#7f4d6d652310][rid#7f4d6da4bdc0/initial] [perdir /var/www/html/sampleapp/] add per-dir prefix: public/address.php -> /var/www/html/sampleapp/public/address.php [Wed May 31 18:51:48.958531 2017] [rewrite:trace2] [pid 5478] mod_rewrite.c(470): [client 192.168.1.29:55447] 192.168.1.29 - - [192.168.1.28/sid#7f4d6d652310][rid#7f4d6da4bdc0/initial] [perdir /var/www/html/sampleapp/] strip document_root prefix: /var/www/html/sampleapp/public/address.php -> /sampleapp/public/address.php [Wed May 31 18:51:48.958539 2017] [rewrite:trace1] [pid 5478] mod_rewrite.c(470): [client 192.168.1.29:55447] 192.168.1.29 - - [192.168.1.28/sid#7f4d6d652310][rid#7f4d6da4bdc0/initial] [perdir /var/www/html/sampleapp/] internal redirect with /sampleapp/public/address.php [INTERNAL REDIRECT] [Wed May 31 18:51:48.958602 2017] [authz_core:debug] [pid 5478] mod_authz_core.c(809): [client 192.168.1.29:55447] AH01626: authorization result of Require all granted: granted [Wed May 31 18:51:48.958634 2017] [authz_core:debug] [pid 5478] mod_authz_core.c(809): [client 192.168.1.29:55447] AH01626: authorization result of <RequireAny>: granted [Wed May 31 18:51:48.958652 2017] [rewrite:trace3] [pid 5478] mod_rewrite.c(470): [client 192.168.1.29:55447] 192.168.1.29 - - [192.168.1.28/sid#7f4d6d652310][rid#7f4d6da53380/initial/redir#1] [perdir /var/www/html/sampleapp/] strip per-dir prefix: /var/www/html/sampleapp/public/address.php -> public/address.php [Wed May 31 18:51:48.958661 2017] [rewrite:trace3] [pid 5478] mod_rewrite.c(470): [client 192.168.1.29:55447] 192.168.1.29 - - [192.168.1.28/sid#7f4d6d652310][rid#7f4d6da53380/initial/redir#1] [perdir /var/www/html/sampleapp/] applying pattern 'public/address/(\\d+)' to uri 'public/address.php' [Wed May 31 18:51:48.958671 2017] [rewrite:trace1] [pid 5478] mod_rewrite.c(470): [client 192.168.1.29:55447] 192.168.1.29 - - [192.168.1.28/sid#7f4d6d652310][rid#7f4d6da53380/initial/redir#1] [perdir /var/www/html/sampleapp/] pass through /var/www/html/sampleapp/public/address.php |
mod_rewriteのウェブサービス
まだリダイレクトをすぐに調べられるサービスもあるようなのでこれを活用するのもいいと思います。
Mod Rewrite Generator
まずはサンプルのURLをいれて挙動を確認してみましょう。.htaccessを自動で吐いてくれます。
Test your htaccess rewrite rules
get句を含んだURLとhtaccessの記述内容に合致しているかをすぐに判定してくれます。いちいちブラウザをたたくよりこっちのほうが便利かも・・
注意点
htaccessの場合、一度設定するとブラウザがキャッシュしてしまい、書き換えてもなかなか反映されないことが多いです。
その場合、ただのリロードや一般的なリロード(F5/Ctrl+F5)では解決しないことが多いです。
chromeでは以下のステップでキャッシュをクリアできます。
- F12で開発ツールを出す
- URLバーの横にあるマークを長押し
- キャッシュの消去とハードの再読み込み
【Chrome】ブラウザの頑固なキャッシュを完全に削除するスーパーキャッシュクリア方法
ちなみにIEとfirefoxでは地道に設定画面からキャッシュをクリアするしかないようです。メンドイ・・・