PHP=システム:Controller
がView
からのリクエストを受け取り、$_POST
データを含んでいます。これで、3つのデータを処理する方法:
a)Controller
はModel
のみを呼び出し、Model
は$_POST
データを処理します。
b)Controller
は、$_POST
データを変数に変換し、Model
に渡します。
c)Controller
は$_POST
データをModel
のドメインオブジェクトに変換し、Model
にのみオブジェクトを渡します。
現在、私はオプションAに従っていますが、それは間違っていると思うので、オプションCの使用を考えています。
MVCによると、$_POST
データを処理する正しい方法は何ですか?
[〜#〜] edit [〜#〜]現時点では、MVCフレームワークを使用していません。
編集2一般に、同じController
がブラウザー、Webサービス、オフラインアプリケーションなどからのリクエストを処理するか、それぞれが独自のController
?
最良のオプションは、#2アプローチを使用して、いくつかの変更を加えることです。
私はそれを次のようなものとして書きます:
_public function postLogin( $request )
{
$service = $this->serviceFactory->build('Recognition');
$service->authenticate( $request->getParam('username'),
$request->getParam('password') );
}
// Yes, that's the whole method
_
Request
インスタンスなどを使用してユーザーの入力を抽象化した場合は、実際に変数を作成する必要はありません。
また、
Request::getParam()
methodをRequest::getPost()
-のようなものに置き換えることもできますが、正しく構造化されたアプリケーションでは、theGET
andPOST
parameters同じ名前を共有しないでください。
コードスニペットに表示されるserviceFactory
は、コントローラーとビューインスタンスの両方に注入するオブジェクトです。コントローラーとビューの間で同じサービスインスタンスを共有できます。
servicesの作成を担当します。これには、ドメインビジネスロジックを domain objects に残したまま、アプリケーションロジックが含まれます)は、ドメインエンティティとストレージ抽象化の間の相互作用をプレゼンテーション層から分離するのに役立ちます。
コントローラはモデルを呼び出すだけで、モデルは$ _POSTデータを処理します。
MVCおよびMVCにインスパイアされたデザインパターンでは、モデルはユーザーインターフェイスもプレゼンテーションレイヤーも全体として認識してはなりません。 PHPの_$_POST
_変数は superglobal です。
モデルレイヤーで使用すると、コードはWebインターフェイスにバインドされ、特定のリクエストメソッドにもバインドされます。
コントローラは$ _POSTデータをモデルのオブジェクトに変換し、オブジェクトをモデルにのみ渡す
これで何を意味するのか完全にはわかりません。ユーザーのリクエストを含む抽象化のインスタンス化について話していたようです。しかし、この場合、コントローラーは上記の構造のインスタンス化/作成を担当します。これは [〜#〜] srp [〜#〜] に違反します。
理解しておく必要があることの1つは、WebベースのMVCアプリケーションのコンテキストでは、アプリケーションのUserがブラウザーであることです。あなたじゃないブラウザはリクエストを送信します。リクエストはルーティングメカニズムによって処理され、コントローラによって配布されます。そして、viewはブラウザに/と応答します。
そしてもう1つは、モデルはクラスでもオブジェクトでもありません。 モデルはレイヤーです 。
通常、同じコントローラがブラウザ、Webサービス、オフラインアプリケーションなどからのリクエストを処理しますか、それともそれぞれに独自のコントローラがありますか?
アプリケーションのすべての形式を処理する単一のコントローラーを持つことができるはずです。しかし、それは条件にすぎません。実際には、3つのユースケースすべてで同じアプリケーションを使用しています。
これを行うには、2つの条件があります。
Request
インスタンスを抽象化する必要がありますこのようにして、1つのアプリケーションですべての要件を満たすことができます。バリアントごとに異なるのは、bootstrapステージのみです。このステージでは、Request
インスタンスを作成し、適切なビューを選択します。
あなたが説明した状況では、RESTまたはSOAPサービスは異なる応答を生成すると予想されるため、変更部分は実際にビューになります通常のWebアプリケーション。
かつては、3層のアプリケーションアーキテクチャがありました。
それはすべてMVCフレームワークに依存します。通常、コントローラーはユーザーとドメインレイヤーを操作するモデルレイヤー間のリンクを行います。
PHPでのMVCの初期の頃は、モデルレイヤーは実際にはドメインオブジェクトであり、その目的のためのモデルと呼ばれていました。データのOO表現のみを提供する、いわゆる永続化を簡素化する、いわゆるシンモデルを使用することを好む人もいます。その場合、コントローラーは、いわゆるアクションを再グループ化して、 HTTPリクエストに関連付けられた処理(脂肪コントローラ)。
他のものは、専用のメソッド(脂肪モデル)を使用して、オブジェクトモデルに前述の処理のほとんどを組み込みました。
ただし、ある時点で、クエリの内容を分析してサニタイズおよび検証する必要があります。これは、ビューがリクエストをフォーマットする方法によって異なります。サニタイズはコントローラータスクである場合があります(このリクエストにはこれらの値のみが含まれている必要があります)一方で、検証は間違いなくモデルタスクです(値はこれらのタイプである必要があります)。
興味深い質問は、いくつかのドメインオブジェクトに影響を与えるアクションにどのように対処するかです。そのためのロジックをどこに置きますか?
現在、モデルレイヤーは、ドメインオブジェクトをコントローラーの邪悪な把握から分離するサービスで構成されており、レイヤー間の依存関係をそれぞれのインターフェイスのみに制限しています。これは、ほとんどの要求処理が行われる場所です。
Symfony2 は、たとえば、この質問に対する賢明な答えを提供します。要求の処理の各ステップは、次のように記述できる専用のコードに実装されます。
その後、サービスジョブはいくつかのステップで中断されます。
CakePHP は、同様の概念に従う単純なコントローラ、およびドメインオブジェクトをカプセル化するサービスである別の一般的なフレームワークです。
一般的な概念についてのより良い洞察については この質問 を参照してください。
他の答えについては this other question を参照してください。
tereško のおかげで、この件に関する貴重な情報を提供してくれました。
私はZendを使用しています。
2番目のオプション。
登録フォームの例
step-1フォームは指定されたコントローラーにポスト値を送信します
step -2 iサーバー側の検証を通じて、フォームの値(メールとURL、空の投稿の値など)を検証します。
ステップ-チェックされた投稿データを変数で送信するか、全体をモデルに送信します。
手順4-コントローラがモデルを呼び出します。
step -5モデルは投稿の値を挿入し、新しいユーザーを作成します。
使用するフレームワークやアプローチに関係なく、2番目のオプションの方が優れていると思います。
注-同じコントローラーがすべてを処理できるのは、アプリケーションロジックによって異なります。
but i prefer to keep different controller for differnt user request and user types
it helps in keeping code readable managebale .
「C」が最適なオプションです。モデルは主に汎用のストアおよびロード操作を想定しているため、生の$ POSTデータをモデルに入れないでください。
例:WebインターフェースとWebサービスで同じモデルを使用できます。 Webでは$ _POSTは有効ですが、Webサービスでは無効です。そのため、モデルはデータの受信方法を気にせず、データを保存およびロードする方法のみを考慮します。
Yiiは間違いなくMVCのクリーンな実装です。
いくつかのMVCフレームワークを見てください。
たとえば、Yiiでは、actionの中にそのようなコードを書くことができます):
_$model = new Model();
if(isset($_POST['Model'])) {
$model->attributes = $_POST['Model'];
}
_
モデルのすべてのattributes
は検証ルールを通過する必要があることに注意してください。 Yii検証は適用中(実際には、適用前)$model->save()
見る: