web-dev-qa-db-ja.com

Zend Framework、$ this-> _forwardが行っていること

_forwardが正確に何をしているのかを誰かに説明してもらいたいのですが、_forwardがアタッチされたビューをアクションにレンダリングしているのか、単にアクションを実行しているのかわかりません。

ビュースクリプトで$ this-> actionに引数を渡すこともできますか?

より一般的には、私の問題は確認ページをコーディングする方法です。たとえば、ユーザーが何かを入力し、確認を表示したい場合、転送はその場合の意味ですか?

21
RageZ

_forwardは内部リダイレクトです。 _redirectがクライアントのブラウザに他のURLに移動するように指示するヘッダーを送信するのに対し、_forwardはディスパッチャに要求を内部的に別の場所にリダイレクトするように指示します。

次の通常の発送順序を検討する場合:

 preDispatch()
 someAction()
 postDispatch()

その進行の任意の時点で_forwardを呼び出すと、次の手順が実行されなくなります。したがって、preDispatch()で_forwardを呼び出すと、someAction()は呼び出されません。 someAction()で_forward()を実行し、viewRendererアクションヘルパーを使用してビューをレンダリングしている場合(フレームワークにレンダリングするビュースクリプトを選択させる)、someAction()でビュースクリプトはレンダリングされません。

リクエストが新しいコントローラー/モジュールに転送されると、ディスパッチプロセス全体がそこで繰り返されます。

以下を使用して、ディスパッチされているアクションを確認できます。

 $action = $this->getRequest()->getParam('action');

$ actionはアクションのURL形式になるため、メソッドの名前が「someKindOfAction」の場合、$ actionには「some-kind-of」が含まれます。これは、コントローラーとモジュールに対しても実行できます。

22
smack0007

Zendでの私の経験は限られており、あなたがすでに見たものをあなたに見せないことを願っていますが ドキュメントによると (12.7.6。ユーティリティメソッド):

_forward($ action、$ controller = null、$ module = null、array $ params = null):別のアクションを実行します。 preDispatch()で呼び出された場合、現在要求されているアクションはスキップされ、新しいアクションが優先されます。それ以外の場合、現在のアクションが処理された後、_forward()で要求されたアクションが実行されます。

だから、それが問題と呼ばれるときの文脈のように聞こえます。後者の場合、最初に呼び出されたアクションを実行し、次に転送されたアクションを実行します。例外は、preDispatchハンドラーから呼び出されている場合です。

10
Karim

_forwardは非常に非効率的であり、常にメソッドを直接呼び出す必要があることに注意することが重要だと思います。 _forwardを実行すると、init()、ディスパッチ前およびディスパッチ後が再度実行されます。 initの内容に応じて、同じデータベースレコードを2回実行(および挿入)できます。

使い方は簡単ですが、無駄です。コードのプロファイルを作成し、すべてが2回呼び出される理由に頭を悩ませている場合は、_forwardが理由です。私のように、クラス全体で使用するためにinit()でいくつかのオブジェクトをインスタンス化すると、すべてを2回インスタンス化することになります。コードで負荷テストを行い、_forward( 'foo')の代わりにfoo()のようにアクション名を直接呼び出すことで、パフォーマンスが向上しました。

ほとんどの人が知っていると思うもう1つのオフトピックのヒントは、可能な限り一重引用符を使用することです。PHPパーサーは文字列の埋め込み変数をチェックする必要があります。実際のパフォーマンスがどれだけかわかりませんこれは、特にオペコードキャッシュを使用している場合に役立ちますが、ベストプラクティスです。

9
Dan

転送は、外部リダイレクトが適切なオプションではない場合に使用されます。ユースケース(少し厄介ですが、私が補うことができる最善の方法):ペット(犬または猫)を追加できるフォームがあります。それぞれに異なるモデルがあります。フォームに犬/猫を選択するための選択を含めます。次に、あなたの行動であなたはします:

if($form->isValid($_POST)){  
  switch($form->select->getValue()){
    case "dog":
      $this->_forward('add-dog','pets','default');
      break;
    case "cat":
      $this->_forward('add-cat','pets','default');
      break;    
  }
}

そして、あなたは別々の行動で猫と犬のために異なることを扱います。これの利点は、すべてのパラメーターが一緒に送信されることです。 $ this-> _ redirect()を使用した場合とは対照的に、POSTパラメータは失われます。これは、意図した動作である場合があります(たとえば、コメントを追加した後、コメントにリダイレクトします)。二重投稿と「ページはデータを再度送信する必要があります...」というメッセージを避けるためにページを一覧表示します。

3
Tomáš Fejfar

私が誓うフレームワークドキュメントの一部は、一般的なレベルでのディスパッチワークフローを説明していました。そこに この図 が、_forwardが何をするかを説明するのは非常に複雑です。

アクション中の場合、_forwardは_$request->isDispatched = false_を設定し、_forwardで指定されたコントローラー/アクションを呼び出す要求を設定します。 postDispatch中に、isDispatchedがチェックされます。falseの場合、新しいリクエストを使用してすべてが再度実行されます。

つまり...アクションでビューを手動でレンダリングしている場合でも、ビューはレンダリングされます。アクションのすべては引き続き発生し、その後も別のアクションが発生します。

[質問編集後に編集]

Forwardは、response/confirm-after-postを対象としたものではありません。リダイレクトを使用してください。 $this->_helper->redirector->gotoUrl()など。

2
Justin