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

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

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

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

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

Q&A

1回答

3030閲覧

MVCのコントローラの役割が理解出来ていない

zbymfw

総合スコア15

PHP

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

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

0グッド

2クリップ

投稿2017/07/22 19:24

###前提
Laravelを使用してwebアプリを作成しています。
恥ずかしながらいつもなんとなくでクラスやロジックの追加修正やなどを行っており、動作はするけどクラス構成やそのクラスの責務が微妙だなあと思うことがよく発生します。

そこで、この場合、みなさんならどう作るのか、もしくはどう作るべきかなどを教えてほしいです。
ただの好みや間違いの指摘でも構いませんので、色々聞ければと思います。

コード

決済を行う処理が有り、流れはだいたい下記の様になっています。

PHP

1class App\Http\Controllers\MyController 2{ 3// フォームからのPOST(決済実行)を受け付ける 4public function postCheckout(App\Http\Requests\MyRequest $req) 5{ 6 // リクエストの基本的なvalidateは実施済みのため、ここでのvalidateは不要 7 try { 8 // リクエストを基に、CheckoutのAPIに投げるデータを作成する 9 $data = $this->makeDataForCheckout($req); // <- (1) 10 // 決済用POSTデータで、決済を実行する 11 $result = $this->checkout($data); // <- (2) 12 if ($result->status !== 'succeeded') { 13 // 決済失敗してる 14 throw new Exception($result); 15 } 16 // 決済が完了した 17 return redirect('/checkout/complete'); 18 } catch (Exception $e) { 19 // 決済 20 Log::error($e); 21 } 22 23 // 決済失敗してる 24 return back()->withInput(); 25}
  1. リクエストを基に、CheckoutのAPIに投げるデータを作成する
  2. 決済用POSTデータで、決済を実行する

PHP

1 2// 1. リクエストを基に、CheckoutのAPIに投げるデータを作成する 3public function makeDataForCheckout(App\Http\Requests\MyRequest $req) 4{ 5 // 金額含む商品情報と、決済ユーザ情報を取得し返す 6 // 決済会社ごとに受け付けるフォーマットが違うため、考慮の必要有り 7 return [ 8 'item' => Item::find($req->item_id), 9 'user' => User::find($req->user_id), 10 ]; 11} 12 13// 2. 決済用POSTデータで、決済を実行する 14public function checkout(array $data) 15{ 16 // 例えばpaypal決済を実行する 17 // -> paypalクラスはただのラッパークラス 18 return $paypal->checkout($data); 19}

私が気になっているところですが、これらの1. 2.のメソッドをMyControllerクラスで持つべきなのか?という点です。

この場合、現状のままだと決済会社が増えるたびにコントローラが膨らんでいきます。
ただ決済会社を増やした場合、各会社ごと受け付けるデータが違うため、どこかしらでメソッドは増やす必要があります。

数バージョン考えてみました。良いと思える順です。

PHP

1 2// 1. データの変換は全てDataConverterクラスで行う 3// DataConverterは常にItemクラスとUserクラスに依存する 4$data = $paypalDataConverter->makeData($req); 5$result = $paypal->checkout($data); 6// -> 決済会社が増えた場合、DataConverterクラスと決済会社クラスの2つを作成する 7 8// 2. $reqをそのままPaypalクラスに渡してチェックアウトする 9// paypalクラスのcheckoutメソッド内で データ変換を行う($paypalDataConverter->makeData($req) などの形) 10$result = $paypal->checkout($req); 11 12// 3. Itemクラスで決済まで行う 13// paypalクラスやデータ変換クラスなどへの依存が生まれるので違和感 14$result = Item::paypalCheckout($req); 15

もやっとしていますが、どうするべきかご指南頂けますと幸甚です。

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

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

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

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

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

guest

回答1

0

それらは全てModelの役割です。

ControllerはURLに従って入力されたデータをModelに丸投げして値を受け取り、
Viewに受け取ったデータを丸投げするくらいしか書く内容はありません。
Modelにバリデートを依頼して、falseが返ってきたら400番エラーを返してリダイレクトするくらいの事は書いても良いでしょう。

ここは窓口Modelクラスを用意して対応しましょう。
また、**オンライン決済インタフェース**を用意しておきます。

私が作ると仮定してちょっと作戦を書いてみました。
下記のような感じの実装になると思います。
(interfaceとclassは1つにつき1ファイルで管理する)

PHP

1interface onlinePayment 2{ 3 public function isValid(); 4 public function checkout(); 5} 6 7// こんな感じのラッパークラスを沢山用意 8class paypalPayment implements onlinePayment 9{ 10 public $req = null; 11 12 function __construct($req){ 13 $this->req = $req; 14 } 15 16 public function isValid() { 17 $result = false; 18 // バリデートを実行 19 return $result; 20 } 21 22 // スタティックなのはテストをしやすくする目的です。 23 public static function convertFrom($req) { 24 $data = null 25 // $data を生成する処理 26 return $data; 27 } 28 29 public function checkout() { 30 $data = self::convertFrom($this->req); 31 // 決済を実行して、失敗なら下記を投げる(このクラスはExceptionを投げて死ぬだけでOK) 32 throw new Exception($result); 33 } 34} 35 36// 窓口クラス 37class paymentWindow implements onlinePayment 38{ 39 public $payments = [ 40 "paypal" => 'paypalPayment', 41 ]; 42 43 function __construct($req){ 44 $payment = $this->payments[$req['target']]; 45 $this->payment = new $payment($req); 46 } 47 48 public function isValid() { 49 return $this->payment->isValid(); 50 } 51 52 public function checkout() { 53 return $this->payment->checkout(); 54 } 55}

空でバーっと書いたのでSyntaxエラーが出るかもしれませんが、一通り出来る方だと思いますので問題ないと判断しました。
窓口クラスが若干重いですが、結局は何処かに書いてメンテナンスしないといけないので、こんな所ですかね?
まぁ、案の1個くらいに思ってください。

投稿2017/07/22 20:45

miyabi-sun

総合スコア21158

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

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

zbymfw

2017/07/22 23:20

@miyabi-sun ありがとうございます!これだけでもとても勉強になります!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問