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

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

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

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

PHP

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

Q&A

解決済

2回答

4396閲覧

PHP 処理の分け方

Z-TALBO

総合スコア525

MVC

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

PHP

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

1グッド

1クリップ

投稿2017/08/16 08:59

###はじめに
今回は、プログラムのコード等に関する質問ではありません。
当然、今回の質問に対して状況や考え方など正解という正解もなく、また不正解ということもないのは理解しております。
例題に関しても、それならそもそももっと細かくわけるなどあると思いますが、アドバイスやいろんな情報を共有できればと思います。

指摘というよりは、こういう考え方などのご意見を求めています。

###処理の分け方等に関して
処理を分ける、、、最近、classなんかもなんとなくこうやれば動くというのはできるようにはなってきましたが、はっきり言って、それぞれの役割や、この処理はこっちなどがまだまだ理解不足であると認めざるを得ません。

MVCをフルスクラッチで書いておりますが、、、初心者にありがちかどうかはわかりませんが、、、
indexがあり値を送信してからの処理などをcontrollerで処理しまくって、DBに関わることだけをmodelに流すということをしていました。

それはそれで動くのは当然な部分もありますし、変な話処理はこっち、DBに関するものはこっちという分け方は、初心者からするとわかりやすい感じもしました。

しかし、もう少しネットの解説なりなんなりを見ていくと、やはりこの認識ではちょっと違う部分の方が多い、、、ということはわかってきつつも、、、
では、実際にこういう処理をする際の流れの中で、この処理はこっち、この処理はこっち、、、
そもそもそれはフロントサイドですればいいということが、分けきれず、逆にいろんなところにメソッドを振ってしまい、あれ、、、これはあっちか、、、あっこっちかという状況になってしまいました。

そこで、例として、ある処理の流れを元に書くならこっちというアドバイスをいただければと思い、質問いたしました。

###例:値をDBにInsertする処理

HTML

1<form action="" method="POST"> 2 <input type="text" name="name[first]"> 3 <input type="text" name="name[family]"> 4 <input type="submit" name="submit" value="送信"> 5</form>

上記のとおり、簡単に姓と名を入力後送信を押すといろいろチェックしたりして、登録するという流れを考えていこうと思います。

今回のファイル構成をざっとですが、、、
[index.php] // 実際に画面に表示されている
[controller.php]
[model.php]
[db.class.php]
他にfunctionやらもあるでしょうが、そのあたりは省略いたします。
db.class.phpには汎用的に使えるclassがあるとします。

さて、私がまず処理を箇条書きで出すとしたら
1.POST送信があったか?
2.name['first'], name['family']に値がセットされているか?
3.2でセットされていなければエラーを出して次の処理にはいかない
4.2でセットされていれば、その文字の正規表現チェック(数字など混ざってないか?)
5.2の値を元にDBにデータがあるかチェック
6.DBにデータがあったら登録せずに、エラーを出す
7.DBにデータがなければ送信された日付を配列に追加する
8.DBにfirst, family, dateを登録する

このように抜き出しました。
実際はもっと細かく、、、があるかもしれませんが、大まかに書き出しました。

次に、私が今の理解度で上記の処理を振り分けるなら、、、
1 = indexでif($_SERVERとかif(filter_inputとかで判定する
2 = controllerに値を飛ばして、さらにmodelに値を渡し、modelでセットされているかチェックする。
3 = modelからの返りがエラーであれば、controllerで$errorを出してindexで表示
4 = modelでそのまま正規表現のチェックを行い、エラーなら3同様
5 = modelからdbにアクセスしチェックを行う(SELECT)
6 = trueだったら既に登録済みなので、3同様
7 = modelで日付をセットさせる
8 = modelからDBにInsertさせる

とりあえず、こう考えてみました。

ということは、indexでcontrollerのインスタンスでInsert()みたいなメソッドで処理が始まり、controllerではmodelのインスタンスを作りmodelでいろいろ処理をしている感じ?になるのかな?という感じです。

まぁ、この例程度の処理であれば、こういう処理をわけるほうがあっちこっちになるかもしれませんが、アドバイス等よろしくお願いいたします。

m.ts10806👍を押しています

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

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

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

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

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

guest

回答2

0

ベストアンサー

色々な意見があり、MVCパターンやら MVVCとか派閥に近いような思想が色々出てます。
なので個人的な意見だと思ってください。

ビジネスロジックという単語もよく出ますが、ビジネスロジックという単語の定義もおそらく思想によって多種多様なので、個人的には使わないようにしています。

#ロジックはControllerに書くかモデルに書くか

ControllerとModelの間にPresenter層を設けます。

ひとつのURLが1つのテーブルのみのCRUDを担当するなんてほぼ皆無で必ず複数のテーブルを処理します。
しかしORMなどはテーブル単位に処理されることが多く、そのURLの処理に特化してトランザクションを管理するレイヤーが必要です。

URL特化のロジックであれば直接ControllerとActionメソッドに書いちゃえば良いじゃんと思われますが、Presenterに書くのはHTTPから切り離した処理を書くようにしています。

つまり、Controllerの処理としてはHTTPとデータロジックの受け渡しです。

HTTPの処理とは

・CookieのデータGET,SET
・SessionのデータGET,SET
・ヘッダーのパラメータのGET,SET
・QueryStringのGET,URL生成
・レスポンスの生成(リダイレクトも含む

などなどです。

つまりControllerを見ただけでHTTPの流れのアウトラインが分かるようにします。
・パラメータ異常->エラーページリダイレクト
・パラメータ異常->入力画面に戻す
・POSTからGETへのリダイレクト
・データ保存して結果出力

などなど。
これらを必ずControllerに書く必要は無く、Utilityクラスを作成してそちらに任せてもいいでしょう。
UtiltiyクラスはPresenter層に影響を与えてはいけません。

#Presenter

Presenterに書くのはHTTPを完全に切り離した入出力です。

入力パラメータは1つのオブジェクトにしておくとメンテナンスが楽です。
出力オブジェクトも1つのオブジェクトにしましょう。それがViewModelになります。

こうすることでPOSTだろうがGETだろうがCookieだろうがSessionだろうが方針を変えてもPresenter層に影響はなく、Presenter層の単体テストが容易になります。

#Model

Modelにはテーブル単体の良く使うQuery実行をメソッド化してまとめておきます。

slect文でjoinが必要な場合は良く使うものであれば左になる(基準になる)テーブルのModelに書きますが
大抵はその処理固有のものになるので直接Presnterに記述するのもありです。

Presenterのメリットとしてはたとえば会員登録のPresenterのメソッドであればそのメソッドからWebで実行したのと同じロジックでテストデータを大量投入したり、テスト用に使いまわすことができるようになります。

またフロントサイトの他CMSを裏で持っている場合、CMSから実行したりなども可能になります。

#その他の意見

Presenter自体をWebApiとして切り出してしまえばWebAPI経由で操作できるじゃんという意見もあると思います。それはその通りです。

考え方は個人個人だと思うので、ひとつの意見としてお納めください。

自分自身もこの考えに固執するつもりはなく、メンバーとの意見を取り入れてある程度みんなが納得できる仕組みで実装するのがいいと思います。

投稿2017/08/16 10:32

Tak1016

総合スコア1408

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

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

Z-TALBO

2017/08/17 01:53

回答ありがとうございます。 まだまだ知識不足で、ViewModelやPresenter自体が聞き慣れず、検索して見てみました。 これを一つ挟むことによるメリットなど、試してみて少し考えてみたいと思います。
guest

0

送信されたパラメータが妥当かどうかを評価する(Validation)部分は、
再利用する可能性が高いため、
その機能だけで独立したクラスにしてもいいかもしれないくらいです。
よくある入力項目(例えば電話番号とか日付とか時刻とか)って、
正規表現一発で済むかもしれませんが、
同じような検査をあちこちに書かずに一箇所にまとめて再利用した方が良いですよね。

アクションメソッドの中にDB処理以外を全部長々を書き連ねてしまって、
今後はそういう風に処理を改めていきたいなと。

投稿2017/08/16 09:23

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Z-TALBO

2017/08/17 01:50

回答ありがとうございます。 確かに再利用ということを考えるとまた違った見方というかできますね。 このページからの値をチェックというより、値のチェックということを考えると、確かに一つそれだけの機能をまとめると良いなと思いました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問