質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

3回答

1046閲覧

クラス内に定義したメソッドについて悩んでいます

bws

総合スコア98

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2018/12/17 04:14

編集2018/12/17 04:29

やっていること

Areaクラスにセレクトボックスを出力するgetSelect()メソッドを定義しました。
view側ではArea::getSelect()で出力できて、シンプルなのでとてもいいなと思っていました。
ところが別のviewで以下のように「すべて」の項目があるセレクトボックスを出力する必要が出て来ました。

html

1<select> 2 <option value="">すべて</option> 3 <option value="0"></option> 4 <option value="1">西</option> 5</select>

困っていること

1、新たに「すべて」を含んだセレクトボックスを生成するメソッドを定義する
2、getSelect()に新たに引数を与えて関数内で対応する

二つの方法を思いつきました。
どちらでも対応できそうですが、この調子でまたちょっと違うセレクトボックスを出力したくなった時に1の方法ですと同じようなメソッドがどんどん増えていくような気がしますし、2の方法ですと与える引数がどんどん増えていくことが想像出来る為どちらもあまり良い方法ではないのではないかと考えています。

セレクトボックスをまるまる生成するメソッドは諦めてoptionのみ返すようにした方がいいのでしょうか?
そもそもこのようなメソッドをクラス内に定義するのは間違いですか?
良い方法があるのでしょうか?アドバイス、参考になるページやオススメの書籍などもあれば教えて頂けませんでしょうか。よろしくお願いします。

コード

PHP

1class Area 2{ 3  protected static $title = 'エリア'; 4 protected static $form_name = 'area'; 5 6 protected static $areas = array( 7 '0' => '東', 8 '1' => '西' 9 ); 10 11 public static function getData() 12 { 13 return self::$areas; 14 } 15 16 public static function getName($id) 17 { 18 $areas = self::getData(); 19 return $areas[$id]; 20 } 21 22 public static function getSelect($id = null) 23 { 24 $format = ' 25 <div class="form-group"> 26 <label for="%s" class="control-label">%s</label> 27 <select id="%s" class="form-control" name="%s"> 28 %s 29 </select> 30 </div>'; 31 32 $data = self::getData(); 33 34 foreach ($data as $key => $val) { 35 $options .= sprintf( 36 '<option value="%s" %s >%s</option>', 37 $key, 38 self::isSelected(strval($key), $id), 39 $val 40 ); 41 } 42 43 $select = sprintf( 44 $format, 45 self::$form_name, 46 self::$title, 47 self::$form_name, 48 self::$form_name, 49 $options); 50 51 return $select; 52 } 53 54 public function isSelected($key, $id) 55 { 56 if ($key === $i) { 57 return 'selected'; 58 } 59 } 60}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

papinianus

2018/12/17 04:30 編集

「すべて」のHTMLでのvalueまたはphp上での配列のキーは何ですか?それはプルダウンが妥当なデータですか?以前に拝見した質問の例を借りると地方のときは複数の選び方のパターンが多くありませんか?チェックボックスが適切ではないですか?
bws

2018/12/17 04:31

検索絞り込み用のセレクトボックスを想定していましてvalueは空('')にしようと思っていました。よろしくお願いします。
bws

2018/12/17 04:39

盲点でした。 そもそもセレクトボックスであれば「すべて」の項目が必要なくなりそうですね…
m.ts10806

2018/12/17 04:49

そこは仕様なので決めてもらって良いかと。「何も選択されない」=「すべて」とすることもできますし、「すべて」を選択させることもできますが、それはあくまで仕様の話なので。
guest

回答3

0

getSelect()にtrue/falseだけを渡す引数を追加して
trueならその「全て」を含みfalseなら今までと同じような作りで良いと思います。
もし「全てだけじゃなく汎用的にしたい」のであれば、key=>valueの配列渡してその配列が定義されているかどうかで決めても良いですし。
拡張性をどの程度持たせるかどうかで決めてください。

投稿2018/12/17 04:20

m.ts10806

総合スコア80765

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bws

2018/12/17 05:09

引数を配列で渡すという考えがなぜかありませんでした。ありがとうございます!
m.ts10806

2018/12/17 05:17

配列をうまく使えば呼び出し元のコードを触る必要がなくなるので メンテナンス性が上がります
guest

0

回答ってほどでもないんですが、オレオレフレームワークのメンテナとしての経験から。

前回の質問でもあった質問者様の違和感は多分正しくて、つまり教科書的なオブジェクト指向からすると変なんだと思います。その理由として大きいのはこのクラスがデータモデルとビューの責務分けができてないからだと思います。

質問欄で伺ったのは、「すべて」に対応して格納すべきデータがあるか、という意味です。なので、これが盲点なんだとするとちょっと困るかと思います(これは設計に左右される問題でもないと思います)。データモデルとしては、データがあれば保存するし(つまり$areasに"全て"を持つ理由がある)、今回のように対応するデータがなければ$areasには保存しないと思います。

そして、getSelectはselect/optionを作るUI用パーツとして、このクラスの外に、ビューを管理するところで、用意される関数だと思います(業務系の画面だと、必須項目で初期値を空欄にするためにvalueが""であるプルダウンと、""のvalueをもたないプルダウンとを局面で出しわけたり、データにはあるが選択不可能なvalueがあったりして、getSelectに該当する関数はかなり色々なリクエストに応えられるように作っておく気がします。なので、このようにhtmlをクラス内で生成して返すのは設計的に危険に思えます)

投稿2018/12/17 13:27

papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bws

2018/12/18 02:12

今回$areasに「すべて」を持たせる必要はなかったので、getSelect側で出し分けるのが自然ですね。 またgetSelectを抽象化してViewを管理する側で管理できるようにがんばってみたいと思います。貴重なアドバイスありがとうございます!勉強させていただきました。
guest

0

ベストアンサー

いろいろとやり方はあると思いますが、定番なのは $args 的なハッシュを渡す方式だと思います。
これはクラス設計というよりは一般的な関数/サブルーチンの設計的な考えですね。
クラス設計的にはオプション的な要素をメソッドで指定したりすることも考えられますが、個人的には無駄に複雑になるだけかな、と感じます。
よくある API のコンストラクタだと両方可能となっているものが多いですね。

投稿2018/12/17 04:30

ssasaki

総合スコア1167

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bws

2018/12/17 05:11

引数を配列で渡すという考えがありませんでした。$argsという言葉自体も知らなかったのでキーワードを頂けて大変助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問