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

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

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

MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

PHP

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

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Q&A

解決済

4回答

1068閲覧

MVCアーキテクチャでViewからDBを参照するのは良しとするか

XNXSXMXR

総合スコア239

MVC

MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

PHP

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

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

0グッド

1クリップ

投稿2020/01/23 10:03

編集2020/01/23 12:11

MVCアーキテクチャのオリジナルフレームワークを使用した案件開発ですが、他のMVCフレームワークでも当てはまるかと思います。
日頃からループの回数を減らすべく意識しているのですが、表題とおりViewからDBを参照する是非について頭を悩ましています。

コーディングというよりも、施策についての質問です。

作成しようとする画面

stdClassのオブジェクト変数「$orderList」があり、中身は以下のようなイメージです。
その中の「lists」プロパティをループさせて、tableタグによる一覧を作成します。

またその中の「order_number」をキーにDBテーブル「order_status」をSELECTし、値を表示させます。

PHP

1// $orderList 2stdClass Object 3( 4 [customer_no] => 1 5 [lists] => Array 6 ( 7 [0] => stdClass Object 8 ( 9 [order_number] => 10000 10 [kubun] => 見積 11 ) 12 [1] => stdClass Object 13 ( 14 [order_number] => 10001 15 [kubun] => 見積 16 ) 17 ) 18)

↓ order_statusテーブル

order_numberstatus
10000了承
10001査定中

↓こんな一覧を画面で表示させる

注文番号区分ステータス
10000見積了承
10001見積査定中

※$orderList変数の中にstatusを含めたいところですが、仕様のため含められません。

MVCアーキテクチャですので、データ処理などビジネスロジックはモデルに、ビューとモデルの連携をコントローラが行うルールで開発していますが、やろうと思えばビューからモデルのクラスを呼び出すことは可能です。

悩んでいる箇所

以下の案①か案②で行うか悩んでおります。

案①:DBへの問合せを1回にする

DBの問合せを1回で済ますには以下のようになるかと思いますが、ループが3回発生します。

1. $orderList->lists をループさせ、order_numberを取り出す

PHP

1foreach ($orderList->lists as $key => $val) { 2 $orderNumbers[] = $val->order_number; 3}

2. $orderNumbers配列を使ってクエリを組み立て、order_statusテーブルの値を得る

PHP

1// ------------------------ 2// Modelにてデータを生成 3// ------------------------ 4$sql = 'SELECT ' 5 . ' order_number ' 6 . ',status ' 7 . ' FROM ' 8 . ' order_sutatus ' 9 . ' WHERE ' 10 . ' order_number in (' . implode(',', $orderNumbers) . ')'; 11 12// DBクラスでSQLを実行し、結果を配列で取得する。 13$buff = Db::fetchAll($sql); 14 15if (!empty($buff)) { 16 foreach ($buff as $key => $val) { 17 // order_number を配列のキーとする 18 $orderStatus[ $val['order_number'] ] = $val['status']; 19 } 20} 21 22// 作られる $orderStatus 配列はこんなイメージ 23// $orderStatus[10000] ... "了承" 24// $orderStatus[10001] ... "査定中" 25

3. tableタグの一覧を生成する

PHP

1// ------------------------ 2// Viewにて画面を生成 3// ------------------------ 4$html = '<table>' 5 . '<tr>' 6 . ' <td>注文番号</td>' 7 . ' <td>区分</td>' 8 . ' <td>ステータス</td>' 9 . '</tr>'; 10 11foreach ($orderList->lists as $key => $val) { 12 $html .= '<tr>' 13 . '<td>' . $val->order_number . '</td>' // 注文番号 14 . '<td>' . $val->kubun . '</td>' // 区分 15 . '<td>' . $orderStatus[ $val->order_number ] . '</td>' // ステータス 16 . '</tr>'; 17} 18 19$html .= '</table>';

案②:tableを作成するループ内でDBに問合せする

ループは1回だけで済みますが、DBへの問合せが件数ぶん発生しますし、ViewからModelを呼び出すのでMVCアーキテクチャの意味から外れる感じがします。

PHP

1// ------------------------ 2// Viewにて画面を生成 3// ------------------------ 4$html = '<table>' 5 . '<tr>' 6 . ' <td>注文番号</td>' 7 . ' <td>区分</td>' 8 . ' <td>ステータス</td>' 9 . '</tr>'; 10 11foreach ($orderList->lists as $key => $val) { 12 // OrderStatusクラス(model)のメソッドを使って、statusを取得 13 $status = OrderStatus::getStatus($val->order_number); 14 15 $html .= '<tr>' 16 . '<td>' . $val->order_number . '</td>' // 注文番号 17 . '<td>' . $val->kubun . '</td>' // 区分 18 . '<td>' . $status . '</td>' // ステータス 19 . '</tr>'; 20} 21 22$html .= '</table>';

長々となりましたが、「うちの開発ルールではこうしている」とか「気にしていない」など、ご教示いただけますと助かります。

以上、よろしくお願いいたします。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/01/23 10:58

あからさまに設計が誤ってるんだから設計通り作るか、 指摘して仕様を治すかどっちか
m.ts10806

2020/01/23 12:08

PHP限定にするより「オブジェクト指向」とか「アルゴリズム」とかをタグに入れた方が良いかと思います。
XNXSXMXR

2020/01/23 12:13

asahina1979さん あからさまな設計の誤りというのは、基底としているオブジェクト変数「$orderList」に、欲しい情報がないことでしょうか?
XNXSXMXR

2020/01/23 12:14

m.ts10806さん タグ追加いたしました。
guest

回答4

0

PHPは門外漢ですが、案2の見た目のループの回数よりDBアクセスの回数の方が全体のコストに影響しそうであるし、案1の方がMVCに沿っていてかつDBアクセスは1回で済むのですから、本件のようなものであれば個人的にはあまり迷うことなく案1を採用すると思います。本当にパフォーマンスに疑義が生じるのであれば、別途、プロファイリングを提案します。

投稿2020/01/23 10:44

dodox86

総合スコア9183

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

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

XNXSXMXR

2020/01/26 11:25

ご回答ありがとうございます。 コスト的にDBアクセスとループとでは比べるまでもない、という感じでしょうか。感覚ではなく計測しておけばよかったと思います。
guest

0

ループとDB問い合わせ(インデックスが正しく効いている前提)って速度への影響が桁違いに違うで、案2を取るメリットはほぼ無いと思います。

投稿2020/01/23 10:37

編集2020/01/23 10:40
tanat

総合スコア18713

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

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

XNXSXMXR

2020/01/26 11:21

ご回答ありがとうございます。 いかにループ回数を減らすか、パズル感覚で攻略する感じが好きで意識はしておりましたが、皆さんご指摘のとおりDBへの問い合わせコストを意識しておりませんでした。
guest

0

ベストアンサー

ループの回数を減らす目的は@XNXSXMXRさんの中ではっきりしていますでしょうか?
そこを示さないと、意にかなった回答を皆さん出来かねるかと思います

パフォーマンスの観点を重視するなら、一般に、DBに対して複数回の問い合わせが発生した場合と、プログラミング言語で同数のループが発生した場合、後者の方がパフォーマンスが良いため案1の方が良いです
それは例えるなら、同じビル内の部屋を訪れるのと、別の駅にあるビルの部屋を訪れるぐらいの差があります

マシンスペックにもよりますが、プログラミング言語のループ処理は数十万回程度であれば一瞬で終わります(稀に例外はあるものの)
グーグルなどで検索すればループ回数毎の処理時間の目安がヒットする(はず)ので、一度確認することをお勧めします

ViewがDB(のアクセスコード)に直接依存することの是非は結構意見が割れそうな気もしますが、
個人的には、変更の多い不安定なものが、変更の少ない安定したものに依存するのが良い、逆は悪い、というお約束を守って設計することをお勧めします

実際の開発において、ViewはViewの都合で、DBはDBの都合で、頻繁に変更が入ることが多いと思いますので、合間に緩衝材としてControllerを挟むのが無難かと思います

また、後々のメンテナンスのことを考えると、Viewのソース内にModelにあるようなコードが存在するのは見る人を混乱させる可能性が高いかな、と思いますし、テストの類もやり難くなりそうだな、とも思いました

投稿2020/01/24 09:52

kanaria007

総合スコア67

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

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

XNXSXMXR

2020/01/26 11:31

ご回答ありがとうございます。 質問を投稿したあと、皆さんのご意見を読ませていただいたときに、憶測ではなく計測すればよかったかも、と思いました。 また、ループ回数にばかり意識せず、もう少し考慮を広げます。 指針についても「変更の少ない安定したものに依存するのが良い」というのをチーム内で共有させたいと思います。
guest

0

ルールをどうされてるかじゃないでしょうか?
うちはMVCに準拠ってルールがあるので、ViewからModelは駄目ですね。
後からの改修にて、後者が理解し辛くなるからです。

個人的には、最短でレスポンスが得られるなら、例外は有りだと思いますが…。

投稿2020/01/23 10:12

NEO_PLANETT-777

総合スコア333

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

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

XNXSXMXR

2020/01/26 11:15

回答ありがとうございます。まぁ確かにルールをどうするか、ですよね。 NGにする理由がいまいち理解せずにルール化するのも・・・と悩んでおりましたが、みなさんの意見をうかがうことで腹落ちできそうです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問