- ベストアンサー
自作フォームクラスでのフォーム生成と配列追加方法
- 自作フォームクラスを使用してフォームの出力やエラーチェックを統括する方法を学びましょう。
- 自作フォームクラスを使用することで、フォームの生成を簡潔にし、フォームに値を追加する際は配列を使用することができます。
- 具体的な実装方法は、addElementメソッドを使用して要素を追加し、配列に値を格納していくことで実現できます。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
流石に、実装の話になってくると様々なアプローチがあると思いますので、このようにするといい、と応えづらいところではありますが、 まず、Formクラスの中身を置いておいて、外面でどのように使いたいか、を考えてみてはいかがでしょう。 <?php $form = new Form(); //まずFormクラスのインスタンスを作りますよね? $hoge = $form->addElement('hoge', 'textarea', 'メッサゲ', 'メッサゲ'); /*=========================================== 私だったら、addElementメソッドでFormクラス内にElementクラスを格納すると同時に、その生成したクラスをreturnして、別の変数に格納してみたりするかも。 ============================================*/ $hoge->setRules(array('maxlength'=>255, 'required'=>true)); /*=========================================== そして外だししてきたクラスのメソッドにsetRulesとか追加してやったりなんかして、 個別にルール設定してみたり。 ===========================================*/ if($form->isPost()){ //$_SERVER変数からREQUEST_METHODを確認する処理のラッパーメソッドでも作ってみて。 if($form->validate()){ $form->save(); //Formクラスに何らかのオブジェクトを渡しておいて、DBに格納するメソッドを作ったり? } } ?> と、こんな感じの流れだと、いいかなぁと。 後は、addElementメソッド生成時にPOSTデータをElementに渡しちゃうとか。 もしくは、上の例だったら <?php $hoge->setValue($_POST['hoge'])?> とかで後から値を突っ込むとか。 これも一つの例で、そのほかHTML_QuickFormのようにグルーピングするような設定が出来たりだとかなんだとか、色々機能足そうと思うと、スマートに行かなくなってくる可能性もあるかと思いますが。
その他の回答 (4)
- hogehoge78
- ベストアンサー率80% (433/539)
>時間は掛かりそうですがひとまずここらでクローズさせて頂きアドバイスを頂いた事を整理しながら >じっくりやってみたいと思います。 そうですね、実装したい内容が、一種のフレームワークのような感じになり、そこそこ大きなものになるので、問いに答えきれない感じでした。 もし、時間があるなら、MVCパターンを利用しているフレームワークを触ってみてください。 クラスの設計において、大きなヒントになると思います。 CakePHPやCodeIgniterなんかが、ドキュメントも豊富なので、雰囲気も掴みやすいと思います。
- hogehoge78
- ベストアンサー率80% (433/539)
Formというクラスを作ったとして、 その中のメンバ変数に各クラスのインスタンスを格納するイメージです。 class Form{ protected $Html = null; protected $Valid= null; public function __construct(){ $this->Html = new Html(); $this->Valid= new Valid(); } } こんな感じで。 後はFormクラスにフォームの動作の一連の動きを振り分けるメソッドとか用意したりすれば良いかと思います。 後は、Elementクラスやソレを継承したそれぞれのinput typeにあわせた、Element_TextとかElement_Textareaとか、作ってみたり。 このように少し大きなものを作る場合は、Singletonパターンと呼ばれるものや、メソッドチェーンなどを覚えると、作りやすいかもしれません。
お礼
お返事ありがとうございます。 >Singletonパターンと呼ばれるものや、メソッドチェーンなどを覚えると、作りやすいかもしれません。 これらについては全く知らないのでこのようなアドバイスを頂けますと大変参考になります。 なんとなくではありますがイメージでき早速作ってはいるのですが1つ質問が。 sizeやmaxlengthは必然的に数字なので妥当性の検証を現状は各フォーム生成のクラス内に定義しており チェックを行うのですが1つのクラス(この場合メインとなるフォームクラスで行うものが妥当でしょうか?)に 書いたものを全てのクラスから実行する事ってできますでしょうか? 思いつく範囲ですがクラスFormに妥当性チェックの定義したとして各クラスのチェックが必要な場合に Formをnewするしか方法はない?と思うのですがあまり効率的ではないような気がしており可能な 方法があれば是非教えて頂きたく思います。
- tany180sx
- ベストアンサー率63% (239/379)
>各クラスが存在してもメインのFormで統括する その方が自然かと。 Formで統括しないとすべてのエレメントクラスを覚えないとだめになります。 ただ、エレメントごとに異なるメソッドもあるかもしれないので $form->name->hoge() みたいに任せられる必要もあるかも。 もうひとつの方向性として、RailsのごとくView(ヘルパー)に特化させる。 <%= form.text_field :name, :style => 'width: 200px;' %> (template)
補足
お返事ありがとうございます。 やはりメインのクラスで管理するべきですよね。ご提案頂いたRailsは全く触った事がないので 今回はphpでやりたいと思います。 ちなみになのですが今回の場合のように複数のクラスを1つのクラス内で使う場合どのように 書けばいいのでしょうか? それぞれのクラスを定義するとこまでは想像がつくのですがどのように1つのクラスでまとめて 使えばいいものかわからない状態です。 宜しければ作成の参考までに一例を挙げて頂けますと幸いです。
- hogehoge78
- ベストアンサー率80% (433/539)
単純にクラス自身に値を返すなら、メンバ変数を利用する感じです。 class Form { protected $form_elements = array(); public function __construct() { } function addElement($type, $name, $label, $arr) { $this->form_elements[] = "<textarea name=\"$name\"></textarea>"; } } このようにメンバ変数に値を溜め込んで、どこかで、別のメソッドで値を返してやればよいのではないでしょうか。 ただ、HTML_QuickFormなどは、addElementメソッドで、別のクラスを呼び出しています。簡単に言えば、フォームの部品(質問の例ではtextarea)をひとつづつ専用のクラスに格納しているようなイメージです。 Formの統括クラスから別のElementクラスを生成して、フォームがPOSTされたりだとかなんだとかした場合に、出力内容を変えたりしているようなイメージですね。 <?php public function addElement($type, $name, $label, $arr){ switch($type){ case 'textarea': $this->form_elements[$name] = new Form_Element_Textarea($name, $label, $arr); break; case 'text': $this->form_elements[$name] = new Form_Element_Text($name, $label, $arr); break; } } ?> とかといった感じで。 最終的にPHPでいうオーバーロードして、__toStringメソッドだとか__callメソッドだとかそういうものも使ったりする感じでしょうか。 もう一度、Formを作るに当たっての機能の塊を紙にでも書き出してみて、そのある塊ごとにクラスを生成することを考えるとより判りやすいかもしれませんね。 ・Formの画面の遷移を統括的に行うクラス ・Formのinputやselectなどの各部品を扱うクラス ・Formの値の検証を行うクラス ・FormのHTML表示を行うクラス ・XSS対策や、CSRF対策を行うクラス などなど。確認画面を生成する場合にも、hiddenを自動的に生成するのか、Sessionに渡すようにするのか、など悩みどころだったり、上記の例の中で、分けずに一つのクラスに集約してしまったりとか。 とにかく一度、分類を明確に切り分けて、それぞれを独立させて作ってみてはいかがでしょうか。
補足
お返事ありがとうございます。 確かに一言でフォームと言えど必要なものは多いですよね。幸いにも?まだ仕様を正確に決めていない 状態ですのでアドバイス頂いたソースを参考にまとめてみたいと思います。 HTML_QuickFormのようにあまりわけても余計にややこしくなるような気もするのでがXSS対策や、CSRF対策を 行うクラスは既に別途作ってあるのでこれを利用しフォームの出力と検証用としてさらにそれぞれのクラスを 作ってみたいと思っております。 それにあたり質問があるのですが多数のクラスを1つの目的(今回の場合フォーム)で利用する際は 単純ですが $form = new Form(); $valid = new Valid(); $html = new Html(); のようにそれぞれ定義しなければ使えないですよね? この場合メインとしてのクラスはFormになると思うのですが各クラスが存在してもメインのFormで統括するような 事って可能でしょうか? 可能でもややこしくなるようであればそれぞれのオブジェクトを定義する方法でもいいのですが今後のメンテ性等を 考慮した場合どのようなものなんでしょうか?
お礼
お返事ありがとうございます。 早速ですが配列として生成する場合で既に詰まっている感じです^^; 時間は掛かりそうですがひとまずここらでクローズさせて頂きアドバイスを頂いた事を整理しながら じっくりやってみたいと思います。 なかなか書籍にも載っておらず理解に苦しむ状態でしたがご丁寧に教えて頂きましてありがとうございました^^