アクション内でgetRequestParameter()の応酬を何とかしたい

symfonyでフォームの内容を処理するようなプログラムを書こうとすると、

$model->setValue1($this->getRequestPamameter('value1'));
$model->setValue2($this->getRequestPamameter('value2'));
$model->setValue3($this->getRequestPamameter('value3'));
(以下続く)

のように、リクエストを延々セットするようなコードが出来上がることがあります。これをもう少し簡単に書くために、Mixinを使ってhydrateObject()という関数をsfComponentに追加してみます。これを利用すると、上のようなコードが

$this->hydrateObject($model,array('value1','value2','value3'...);

のように一行で書く事が出来ます。

やり方は簡単です。以下のクラスをlib/以下に、sfHydrateRequestParameters.class.phpという名前で保存してください。

class sfHydrateRequestParameters
{
    public function hydrateObject($component,&$object,$params = array() )
    {
 
        foreach($params as $key => $val){
            $default = null;
            if(is_numeric($key)){
                //    "param1",
                $param = $val;
                $method = "Set".sfInflector::classify($param);
            }else{
                $param = $key;
                if(is_array($val)){
                    if(array_key_exists("method",$val)){
                        //    "param3" => array("method"=>"Param3,"default"=>3),
                        $method = "Set".$val["method"];
                    }else{
                        //    "param4" => array("default"=>3))
                        $method = "Set".sfInflector::classify($param);
                    }
                    if(array_key_exists("default",$val)){
                        $default = $val["default"];
                    }
 
                }else{
                    //    "param2" => "Param2",
                    $method = "Set".$val;
                }
            }
            if($v = $component->getRequestParameter($param,$default)){
                call_user_func_array(array($object,$method),array($v));
            }
        }
    }
}
sfMixer::register('sfComponent', array('sfHydrateRequestParameters', 'hydrateObject'));

一番最後の行にある、sfMixer::registerが、このファイルをロードした瞬間にsfComponentに本関数をMixinします。

6 Responses to “アクション内でgetRequestParameter()の応酬を何とかしたい”

1
mshk - 17/02/07

配列から Propel のモデルオブジェクトを初期化するのには、fromArray() も使えますよ。

$article = new Article(); $article->fromArray(array( 'title' => 'My first article', 'content' => 'This is my very first article.\n Hope you enjoy it!', ));

2
tumf - 17/02/07

mshkさん いえ、配列ではなく$this->getRequestParameter()の戻り値で初期化し たかったんです。

3
mshk - 18/02/07

趣旨を取り違えていました。 失礼しました。

4
brtRiver - 20/02/07

Definitive GuideのFormの章にこんなコードありました。 getRequestParameter()の値をつかってるぽいです。 (試してもない斜め読みなので見当違いならすいません)

$author->fromArray( $this->getRequest()->getParameterHolder()->getAll(), AuthorPeer::TYPE_FIELDNAME );

5
tumf - 23/02/07

brtRiverさん

この書き方は始めて知りました、なるほどありがとうございます。

次回のエントリーで続編のネタにしようと思っていたのですがリクエストのすべての値をsetするような仕組みは問題がありますね。

6
brtRiver - 24/02/07

投稿後ソースを追ってみたのですが、 AuthorPeer::TYPE_FIELDNAMEという書き方ではなく BasePeer::TYPE_FIELDNAMEでないと動きませんでした。 (ドキュメントのミスかな?)

リクエストのすべての値をsetするような仕組み 実際はgetAll()そのものを渡すのではなく ワンクッション必要だとは感じました。

Leave a Reply

Name (required)
Mail (will not be published) (required)

Your Comments:

Spam Protection by WP-SpamFree