Road to guesswork vol.2
OZACCさんのblogで触れていただいたので、今日はguessworkにおけるフォーム処理について書きます。
guessworkのActionは、標準ではフォームから送信された値についてはまったく関知しませんので、フォームから送信された値を参照したい場合はコントローラにフォーム変数設定用のインタセプタをセットしておく必要があります(但し、呼び出すActionクラスのメソッドを確定するために "mode" という名前の値のみ内部で参照しています)。
// すべてのモードにおいてParametersInterceptorを適用
$controller->addInterceptor("*", new ParametersInterceptor());
addInterceptor()メソッドの最初の引数にはインタセプタを適用するモード名を記述し、2つめの引数にはインタセプタオブジェクトを渡します。上の例ではモード名をアスタリスクにしているため、すべてのモードにおいてインタセプタが適用されます。特定のモードでのみインタセプタを適用させたい場合は、"input,confirm" のように記述します。
ParametersInterceptorが適用されると、「フォーム要素の名前をすべて小文字に変換したもの」と同じ名前のインスタンス変数が存在する場合に、その変数に値がセットされます。例えば、
<input type="text" name="id"> <input type="text" name="user_name"> <input type="text" name="UserAddress">
というフォームで入力された値を受け取るには、Actionクラスで以下のような変数を定義しておきます。
class FooAction extends AbstractAction
{
var $id;
var $user_name;
var $useraddress;
}
ParametersInterceptorは非常にお手軽ですが、原理的にはすべてのインスタンス変数についてWeb上から値を設定することができてしまうため、インスタンス変数の初期化を怠ると大穴が開いてしまいます。そこで、通常はSetterメソッド経由で値がセットされるSetParametersInterceptorを使用します。SetParametersInterceptorの場合は、「フォーム項目名を小文字にしてアンダースコアを除いた文字列」の先頭にsetを付けたメソッドが存在するとそのメソッド経由で値がセットされます。前述のフォームを受ける場合は、以下のようなメソッドを定義します。
class FooAction extends AbstractAction
{
function setId() {}
function setUserName() {}
function setUserAddress() {}
}
なお、PHP4ではメソッド名に大文字・小文字の区別が無いため、setid()やsetusername()といったメソッド名でも値を受けることができます。これだからPHPは…。
それから、ライセンスについて。
当初は導入の簡便さを考えSmartyも内包しようと思っていたので(必然的に)GPLになる予定でしたが、やっぱりguesswork単体で配布することにしました。ライセンスはApache License, Version 2.0になると思います。

otsuka, June 30th, 2004 at 05:15 [Comment]
なるほど。Actionのインスタンス変数にリクエストパラメータをセットする辺りは、WebWork的ですね。
juno, July 1st, 2004 at 15:07 [Comment]
そうです。この部分は、WebWorkのアプローチが一番シンプルな気がしたのでかなり参考にしています。
セキュアに作るにはgetter定義が必須というのがちょっとどうにかしたい所なんですが、PHP4のOOPの範疇で考えるとなかなか難しいです。