2

Voice of the ElePHPant のこのエピソードでは、 22:00 頃に Zend Framework 2 でZend_Formどのようになるかについて話し始めます。Zend\Form

フィルタリングと検証は、フォームにバインドされるのではなく、モデルに関連付けられます。これにより、モデル レベルでビジネス ルール (検証とフィルタリング) を持つことができます。

Zend Framework 1.11 で開発しており、モデルは Doctrine 2.2 エンティティです。エンティティにフィルタと検証チェーンをアタッチするにはどうすればよいですか? エンティティの検証をエンティティ自体に適用したい、@LifecycleCallbacksまたはフィルタリングと検証をエンティティ自体に適用したい。そうすれば、データがどこから来ても (Web フォーム コンテキスト、Web サービス、またはコマンド ライン コンテキストから)、データベースにフラッシュされる前にデータを検証できます。

ヘルプとコード例をいただければ幸いです。ありがとうございました!

4

4 に答える 4

2

ZF2 Forms RFC http://framework.zend.com/wiki/display/ZFDEV2/RFC+-+Formsについて私が理解していることから、プロパティで Filter / Validate アノテーションを宣言することにより、モデル / エンティティにアノテーションを付けることができます。

次に、モデルをフォーム オブジェクトにバインドする必要があり、フォームは相対注釈を読み取ってそれ自体に適用します。この実装で私が目にする問題の 1 つは、これらの定義がフォーム オブジェクト内にカプセル化されているため、検証とフィルタリングのロジックが実際には分離されていないことです。

フォームオブジェクトがモデルの検証ルーチンを呼び出すのが良いでしょう(これがパイプラインにあるかどうかはわかりません)。もちろん、フォーム コンポーネントがモデル内で行うことを (注釈を読み取ることによって) シミュレートし、それをローカルに (ZF2 で) 適用することも可能です。このコンポーネントは現在開発中であるため、完成が近づいたらぜひプレイしてみたいと思います。

とにかく、ZF 1.11 (そして私自身もこの実装を使用しました) では、モデル内で検証ルーチンを定義でき、$model->validate() によって生成されたエラー メッセージを Zend Form エラー スタックに挿入できます。

// element
$form->getElement('my_element')->addErrors($model->getErrorMessages());

// form
$form->addErrors($model->getErrorMessages());

したがって、次のような実装になります。

$form = new My_Form();
if ($this->_request->_isPost())
{
   $data = $this->_request->getPost();
   $model = new \Entities\MyModel();
   $model->populate($data);
   if (!$model->isValid())
   {
      $form->addErrors($model->getErrorMessages());
   }
   if ($form->isValid())
   {
      // continue to save the model etc...
   }
}
于 2012-04-19T11:04:40.843 に答える
0

これは注意が必要ですが、Zend Framework 1.X で似たようなものを構築したい場合は、おそらく を拡張する必要がありますZend_Form

EntityManagerそのようにして、 (またはジェネリックDoctrine\Common\Persistence\ObjectManagerをエンティティと共に依存関係として受け入れるクラスを構築できます。

その後、エンティティに関連付けられたメタデータを分析するか、そのエンティティに対してチェックする必要がある一連のフィールドを定義できます。通常、Doctrine\Common\Persistence\Mapping\ClassMetadataコンストラクターで次のようにインスタンスを操作します。

// in class Your\Form\EntityDriven
// $this->em is the EntityManager passed in
// $this->entity is the Entity object passed to the constructor
$class = $this->em->getClassMetadata(get_class($this->entity));
foreach ($class->getFieldNames() as $fieldName) {
    // Add fieldst to the form based by their eventual @Column(type="...")
    // Eventually, you could use your own AnnotationDriver to get more 
    // constraints as Symfony 2 does
}

それは実際にうまくいくはずです。ただし、バリデータはフォーム インスタンスにアタッチされます。フォームを永続化するにはpersistData、次のようにパブリック メソッドをオーバーライドするだけです。

public function persistData()
{
    $this->em->persist($this->entity);
    $this->em->flush($this->entity);
}

@postPersistまたはのようなライフサイクルイベント内に検証を配置しません@preUpdate。これらの場合の永続化を防ぐ唯一の方法は、例外をスローすることです (外部リスナーを使用する場合を除きますが、それはさらに複雑です)。閉じた になりEntityManagerます。

Zend Framework 2 に適用された概念に興味がある場合、新しいZend\Form( diff を参照) コンポーネントはハイドレーターを使用してモデルに値を割り当てるため、モデルと直接やり取りするのではなく、ロジックを使用してセッター/ゲッターまたはパブリック プロパティ (例として)。入力フィルタリングはZend\InputFilter、フォームなしでも使用する必要があるため (やりたいこと)、新しいコンポーネントとして移動されました。検証は既に分離されていますが、通常、データが有効でない場合はハイドレーターを実行しないでください。EntityHydratorこれで、 andを書けるはずですEntityValidator。貢献したい場合は、DoctrineModuleでプル リクエストを送信してください:)

于 2012-04-19T09:30:29.063 に答える
0

まず、皆さんの回答に感謝したいと思います。皆さんの解決策を試してみて、何が自分に合っているかを確認することを約束します。次に、これを見つけました: http://www.spiffyjr.me/2011/07/15/more-doctrine-2-and-zend-framework-integration-goodies/そしてもちろん、その記事の会社の github https:/ /github.com/SpiffyJr/Spiffyは私の質問に対する解決策のように見えますが、本番用に安定しているかどうか、またはさらに改善/開発されるかどうかはわかりませんが、次の機会にそれも試してみます. そして、私の質問に対する別の答えは、教義 2 で zend フレームワーク 1.X で symfony バリデーターを使用することかもしれません。

于 2012-04-19T13:55:57.453 に答える
0
  1. 私のアプローチは次のとおりです。

a) Web クライアント側の検証でエラーが発生した場合、または追加のクライアント タイプが追加された場合に備えて、クライアント側 (Web フォーム) およびモデル内に検証を行います。

b) モデル内の検証ルールも単体テストできます。これは、ルールが確実に機能することを保証するのに最適です。

  1. すべてのフォームを手作業で開発し、JQuery 検証プラグイン (http://bassistance.de/jquery-plugins/jquery-plugin-validation/) を使用してクライアント側の検証を追加するため、Zend_Form は使用していません。

  2. すべての検証はクライアント側で行い、ライフサイクル コールバックを使用して preInsert メソッドと preUpdate メソッドを Doctrine 2 モデルにも実装しました。

  3. ただし、Zend_Validate クラスは冗長すぎるため使用しませんでした。そのため、Doctrine 2 モデル マッピングのような注釈を使用して構成できる Symfony Validation クラスを使用しました。詳細はこちらhttp://ssmusoke.wordpress.com/2012/03/04/doctrine-2-day-2-model-validation-using-symfony-validator-service-in-zend-framework/

于 2012-04-19T09:35:17.110 に答える