Mapleでのmod_rewriteによるURLカスタマイズ

4月 18, 2007 · Posted in PHP 

最近ある程度の規模の開発を行う場合にフレームワークとして Maple を使用している。
元々は独自に OtokomaMVCと言う漢前なフレームワークを作って使っていたのだが、後付後付で機能を追加していった結果少し重くなってきたり、ごちゃごちゃしてしまったりしてしまったのだ。

本当は Symfonyが気になっているんだけど、PHP5専用と言うことで今のところ恩恵にあづかれず・・・
というわけで、Ethna, Mapleでどっちにしようかな〜と思い何となく性に合ってそうなのが Mapleだったので Mapleを使用している。

今回はそんな Mapleを使うにあたって個人的に気になったことを・・・

フレームワークを自作したときもそうだったけど、
基本的には指導するためのURLとして index.phpなど1つのファイルに集約させるのが動作上はシンプルだ。
Mapleも同じ方法で動作する。

http://domain/index.php?action=[ アクション名]

のようにパラメーター actionが変わるだけ。

この方法に欠点があるとすると、ログ解析時に全て index.phpと判断されてしまうところだ。
フォーム表示 → 確認画面 → 完了
と言う基本的な流れが全て index.phpで呼ばれてしまうため、どのアクションがどれだけ呼ばれたか?と言うのが分からなくなってしまう。
上記の流れを見たときに、フォームまで表示したが確認処理はしていない・確認処理まではしたが完了迄は至らないと言うのがログ解析で判断出来ると、問題を特定出来る可能性が高くなり完了というゴールへ到達する為の改善を行う為の指針となる。
これが分かると分からないとでは、結構大きく違うのだ。

そこで登場するのが Apacheの mod_rewrite。
.htaccessなどの設定で URLの書き換えを行うことが出来るのだ。
例えば、action.php → index.php?param=action のように書き換えられる。このときログ上は action.phpが呼ばれるように見えるのだ。
mod_rewriteを使えば、いたずらに呼出元のファイルを作ることなく index.phpの1つのファイルだけで処理が出来る。優れものなのである。

自分がよく行う方法としては以下の方法。

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*).php?(.*)    index.php?action=$1&$2 [QSA,L]

Mapleはここのアクション名がなんだか長くなる性質があるので、必ずしも上記のみとは限らないのだが、、、
ま、考え方はこんな感じです。

が、しかし、これでは Mapleではうまくいかなかったのである。
例えば フォームからPOSTで test_action.php を呼出、テキストボックスなど幾つかの項目から値を送信する場合に問題があった(name=maji, email=maji@majima.net をPOSTで送信したとすると)。

URLとしては、 test_action.php が呼び出され。上記変数は POSTで送られるため URLには現れてこない。
これを、rewrite で操作をするとこの呼出を index.php?action=test_action に変換し POSTで送られたものはそのまま継続して送る形になる。 いわば GETとPOSTの混在である。

Mapleでは POSTとGETを同時に送ったときに問題があった。これに気がつくのに結構かかった。rewriteの設定を疑っていたので・・・

具体的には、Mapleの core/Request.class.php の Request() メソッドのところ。

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $request = $_POST;
} else {
    $request = $_GET;
}

の部分だ。

REQUEST_METHODが POSTの時は、Mapleでは POSTで送られた変数しか処理されないようになっていた。
いくら Rewriteで action=test_action とか送っても無駄だったわけである。
そこで、Rewriteでも機能出来るように次のように改変しちゃった。

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $request = $_POST + $_GET;
} else {
    $request = $_GET;
}

これでなんとか動くようになった。

もし、違う方法があるよ・・・と言うことでしたらコメントお願いします。


Comments

Leave a Reply