web-dev-qa-db-ja.com

モデル/ビュー/コントローラーモデルの検証に最適な場所は?

私はMVC設計パターンを広範囲に使用するPHPプロジェクトに取り組んでいます。フォームに検証を追加することを検討しており、検証に適した場所について興味があります。

フォームの生成方法により、ポストバックデータの検証は、ビューコンポーネントではるかに単純で繰り返しが少なくなります。応答データを検証するビューを持つことは容認できますか、またはこれをコントローラーまたはモデルに実装する必要がありますか?

利点は何ですか?

50
Lea Hayes

クライアント側でデータを検証する場合(つまり、Javascript検証)、絶対に十分ではなく、まったく安全ではない場合は、Viewで実装する必要があります。

サーバー側でデータを検証している場合、検証にアプリケーションのビジネスロジックは必要ありません(つまり、ユーザーのアカウントに十分なクレジットがあるかどうかを確認していません)、コントローラーで検証する必要があります。

検証にビジネスロジックが必要な場合は、モデル内に実装し、コントローラー経由で呼び出します。

ポストバック検証は、多くのプレッシャーと遅延をかけるため、良くありません。そして、唯一の利点はプログラマーにあります(説明されるべきではありません)。

ほとんどの検証に正規表現を使用できます。これは、PHPおよびJS。

31
AbiusX

検証に適した場所はModelです。

これは、モデルが表すデータの検証を実行しているため、最も理にかなっています。 CRUDの更新に関しては、モデルは常に何らかの方法で使用する必要があります。

  • ビューからデータを変更する場合は、検証を確認する必要があります。

  • データを変更するコントローラーがある場合は、検証を確認する必要があります。

  • そして最後に、モデル自体がデータを変更している場合でも、検証が必要です。

この状態を達成する唯一の方法は、検証をモデルに入れることです。

パフォーマンスと応答の高速化のため、モデルに検証を実装した後、何らかのクライアント側(JS)を追加して、すぐにエンドユーザーに通知する必要があります。

検証は常にデータに関するものです。なぜデータを検証するのですか?したがって、保存する情報の整合性を保つことができます。モデルレベルで検証を行うことにより、理論的には常にデータを正確にすることができます。これは常に必需品です。そこから、ビジネスロジックとクライアントサイドに追加の検証を追加して、アプリケーションをより使いやすくすることができます。

95
Mike Lewis

モデルでの検証は最も一般的なアプローチであるようで(最終的には$obj->isValid()のようなものになります)、これは多くの状況に適しています。

ただし、ユースケースに応じて、モデルの外部で検証を実行する正当な理由がある場合があります。別の検証コードを使用するか、コントローラーなどで実行します。

  • 検証全体の問題の多くにモデルがアクセスできない情報が含まれる場合(たとえば、管理ユーザーが通常のユーザーができない変換を実行できる場合、または特定の日付後に特定のプロパティを変更できない場合)、すべてをチェックすることができますこれらの制約は同じ場所にあります。
  • また、テスト用のオブジェクトを構築するときに、非常に緩い検証規則を適用することが便利または必要な場合があります。 (「買い物かご」オブジェクトには通常、関連するユーザーが必要です。ユーザーは有効なメールアドレスなどを必要とします。100%有効な買い物かごオブジェクトは、買い物かごの単体テストで作成するのに不便です。)
  • 歴史的な理由により、検証ルールが変更される場合があります(以前は必要なかった「性別」を強制するなど)ため、異なる方法で処理する必要のあるデータのバージョンが異なる場合があります。 (異なる検証規則は、バルクデータインポートにも適用される場合があります。)
  • 検証が非常に複雑な場合、呼び出し元にとって最も有用なものに応じて、異なるエラーメッセージを提供する(またはまったく提供しない)ことができます。他の状況では、trueまたはfalseだけで十分な場合があります。

モデルのisValid()メソッドへの引数を介してこれらのさまざまなユースケースを処理することは可能かもしれませんが、検証スタイルの数が増えるにつれて、これはますます扱いにくくなります。 (そして、1つの「1つのサイズがすべてに適合する」isValid()メソッドは、ほとんどの非自明なプロジェクトでは最終的に不十分であることが最終的に保証されると思います。)

1
mjs

投稿された値を検証してサニタイズまたはクリーニングすることと混同しないでください。投稿された値を取得し、コントローラー内の値から悪意のある要素を削除してスクラブする必要があります。次に、データをモデルに送信して、期待される値または形式を検証します。これらのアクションを2つの手順に分割することにより、悪意のあるコードが実装されるリスクを減らします。 「誰も入力しない」ポリシーを使用している場合、この方法はうまく機能します。一部のプログラマーがだらしないか怠け者になる可能性があることを知っています。もう1つの良い面は、モデルが肥大化して過度に機能するのを防ぐことです。このアプローチは、アプリケーションの負荷を分散し、パフォーマンスを向上させるのにも役立ちます。

0
Carl Barrett