2015年2月21日土曜日

良くある備忘録1:リダイレクト・フォワード

○基本
【モジュール名】/【コントローラ名】/【アクション名】.phtml
別のアクションのテンプレートを読み込む

【モジュール名】/【コントローラ名】/【別アクション名】.phtml
$this->render('【別アクション名】');




○リダイレクト
/hoge/foo にリダイレクトする。
$this->_redirect('/hoge/foo');

http://www.example.com/hoge/foo/bar にリダイレクトする。
$this->_redirect('http://www.example.com/hoge/foo/bar');

http://www.example.com/hoge/foo/bar?a=1&b=2 にリダイレクトする。
$this->_redirect('http://www.example.com/hoge/foo/bar?a=1&b=2');

/【コントローラ名】/【アクション名】 にリダイレクトする。
$this->_helper->redirector('【アクション名】', '【コントローラ名】');



○フォワード
別のアクションにフォワードする
$this->_forward('【別アクション名】');
【モジュール名】/【コントローラ名】/【別アクション名】

別のコントローラにフォワードする
$this->_forward('【別アクション名】', '【別コントローラ名】');
【モジュール名】/【別コントローラ名】/【別アクション名】

別のモジュールにフォワードする
$this->_forward('【別アクション名】', '【別コントローラ名】', '【別モジュール名');
【別モジュール名】/【別コントローラ名】/【別アクション名】

パラメータを指定してフォワードする
$params = array(
    'a' = '1',
    'b' = '2'
);
$this->_forward('【別アクション名】', '【別コントローラ名】', '【別モジュール名】', $params);
【別モジュール名】/【別コントローラ名】/【別アクション名】/a/1/b/2

参考:http://pentan.info/php/zend_fw/redirector.html



○リダイレクトとフォワードの違い
リダイレクトの場合、クラアイアントがページXを要求すると、サーバがページYを要求する指示をクライアントに戻します。これによって“クライアントは自動的に”ページYを要求し、結果としてページYがクライアントに戻されます(ページXとページYは、必ずしも同一サーバからのレスポンスではない)。これに対しフォワードは、クライアントがページXを要求すると、“サーバ内で”ページXからYへ処理が移送され、ページYが応答として戻されます(ページXとページYは、必ず同一サーバからのレスポンス)。

 以上の説明を図示すると以下のようになります。
リダイレクトは、サーバからクライアントに異なるページYにアクセスする要求を返すことでページYへの遷移を実現する。これに対し、フォワードはサーバ内でページYに処理を転送し、ページYを結果としてクライアントへ返すことでページ遷移を実現する

 この結果、「リダイレクト」と「フォワード」には、以下のような違いが発生します。

    リダイレクトよりもフォワードの方がパフォーマンスが良い
    リダイレクトがクライアントとサーバ間を2往復(ラウンドトリップ)する非効率な処理であるのに対して、フォワードは通常のリクエスト同様に1回のリクエスト/レスポンスで処理が完結します。これは、単純に2倍のトラフィックが発生するというだけのことではありません。リダイレクトによって発生した2回目のリクエストは、待ち行列の末尾に配置されるため、特にトラフィックの多いサーバにおいては、要求待ちによる遅延が発生する可能性があります。一方、フォワードは、1つのリクエスト処理内の連続したロジックとして処理されるため、こうした遅延の心配はありません。

    フォワードはサーバ内部の転送にのみ使用できる
    遅延が起こらないからといって、ページの自動的な転移を常にフォワードで行えば良いというわけではありません。フォワードは、「サーバ内」で処理を転送するというその性質上、同一サーバ内ページ(クラス)間でしか利用することができません。外部のサーバ上のページに対して移動したいという場合には、リダイレクトを使用する必要があります。

    リクエスト情報を引き継げるのはフォワードのみ
    リダイレクトでは、ページA、Bへの要求はまったく独立した「2つの」リクエストとして扱われるため、リクエストパラメータやリクエスト属性などの情報を両者で共有することはできません。しかし、フォワードでは、ページA、Bの処理は「1つの」リクエスト処理として扱われるため、リクエストパラメータやリクエスト属性はすべて引き継がれます。




参考:http://www.atmarkit.co.jp/fjava/javatips/062jspservlet029.html