3

PHP 5.3 の class_alias を使用して、Symfony 1.4 (Doctrine) フォームの処理を支援しています。単一のアクションを使用して複数のフォーム ページを処理しますが、switch ステートメントを使用して使用するフォーム クラスを選択します。

public function executeEdit(sfWebRequest $request) {
  switch($request->getParameter('page')) {
    case 'page-1':
      class_alias('MyFormPage1Form', 'FormAlias');
    break;
    ...
  }
  $this->form = new FormAlias($obj);
}

これは、Web サイトを閲覧するときに見事に機能しますが、次のようにページが複数回読み込まれるため、機能テストに失敗します。

$browser->info('1 - Edit Form Page 1')->

  get('/myforms/edit')->
  with('response')->begin()->
    isStatusCode(200)->
  end()->

  get('/myforms/edit')->
  with('response')->begin()->
    isStatusCode(200)->
  end();

2 番目の要求に対して 500 応答が返され、次のエラーが表示されます。

最後のリクエストがキャッチされない例外をスローしました RuntimeException: PHP が /.../apps/frontend/modules/.../actions/actions.class.php 行 225 で警告エラーを送信しました (クラス FormAlias を再宣言できません)

これにより、フォームの送信をテストすることが非常に難しくなります (通常、フォーム自体にポストバックされます)。

おそらくこれは、Symfony のテスターが同じようにスループットをクリアしていないためです。「unalias」またはこの種の再宣言を許可する方法はありますか?

4

3 に答える 3

2

別の解決策として、インスタンス化するクラスの名前を変数に割り当てて、次のようにすることができます。

public function executeEdit(sfWebRequest $request) {
  $formType;
  switch($request->getParameter('page')) {
    case 'page-1':
      $formType = 'MyFormPage1Form';
    break;
    ...
  }
  $this->form = new $formType();
}

これは class_alias を使用しませんが、インスタンス化を 1 つの場所に保持します。

于 2010-08-03T11:32:08.473 に答える
1

それが可能かどうかはわかりませんが、マニュアルから判断すると、ノーと言えます。クラスがエイリアス化されると、それをリセットしたり、別の名前で再宣言したりする方法はありません。しかし、繰り返しになりますが、なぜ別名を使用するのでしょうか?

caseあなたのコードから、追加の各ブロックでエイリアシングを行っていると思います。しかし、そうであれば、それらのブロックでフォームを単純にインスタンス化することもできます。

public function executeEdit(sfWebRequest $request) {
  switch($request->getParameter('page')) {
    case 'page-1':
      $form = new MyFormPage1Form($obj);
    break;
    ...
  }
  $this->form = $form;
}

を使用する場合は、とにかくクラス名を switch/case ブロックにハードコーディングしていclass_aliasます。使うメリットはありません。動的に実行したい場合は、「page」から「className」への配列マッピングを作成してから、適切なクラスを検索するだけです。

public function executeEdit(sfWebRequest $request) {
  $mapping = array(
      'page-1' => 'MyFormPage1Form',
      // more mappings
  );
  $form = NULL;
  $id = $request->getParameter('page');
  if(array_key_exists($id, $mapping)) {
       $className = $mapping[$id];
       $form = new $className($obj);
  }
  $this->form = $form;
}

このようにして、マッピング全体を構成ファイルに入れることもできます。または、FormFactory を作成することもできます。

public function executeEdit(sfWebRequest $request) {
    $this->form = FormFactory::create($request->getParameter('page'), $obj);
}

Symfony Components DI Containerを使用している場合は、ハードコーディングされたファクトリの依存関係を取り除き、サービス コンテナーを使用してフォームを取得することもできます。それが最もクリーンなアプローチIMOです。基本的に、class_aliasここでの使用は私には不適切に感じます。

于 2010-08-03T10:54:56.127 に答える
0
function class_alias_once($class, $alias) {
    if (!class_exists($alias)) {
        class_alias($class, $alias);
    }
}

これ自体で問題が解決するわけではありませんが、この関数を使用することで、エラーが発生しないことが保証されます。多分これはあなたの目的には十分でしょう。

于 2010-08-03T10:51:15.617 に答える