今回はphalconのレスポンスの書き方と挙動について書いていきます。サンプルは全てコントローラのアクションメソッド内での処理を想定しています。また、Phalcon\Mvc\ApplicationのuseImplicitViewがtrueの前提で記載していきます。
基本的な挙動
- Phalcon\Mvc\ApplicationのuseImplicitViewがtrueの場合、viewのstartメソッド内のob_start()によって出力は全てバッファリングされる。(router->dispatch()とdispatcher->dispatch()の間で実施される)
- アクションメソッドでreturn falseを返した場合は明示的にバッファリングが解除されることはなく、スクリプト終了時にバッファリングされたデータが全て出力される。また、DIコンテナ内のSharedなresponseがhandleメソッドで返却される戻り値となる。
- アクションメソッドでreturn false以外のレスポンスを返すとviewのfinishメソッド内のob_end_clean()によってバッファの内容がクリアされ、バッファリングが解除される。useImplicitViewがtrueの場合は、テンプレートエンジンによるレンダリングが行われる。
OKパターン1(何もreturnしない)
$this->response->setContent('abc');
return; //=>テンプレートエンジンによるレンダリング(view)
setContentの内容(上記の例だと’abc’)は反映されず、テンプレートエンジンに応じてレスポンスが返される。$this->response->send()を入れたとしても、バッファリングされて、view->finish()内のob_end_clean()によってクリアされるので意味が無い。
OKパターン2(Responseをreturn)
$this->response->setContent('abc');
return $this->response; //=>"abc"(response)
→返却するresponseオブジェクトをベースにレンダリングする。$this->response->send()を入れたとしても、バッファリングされるが、その後、view->finish()内のob_end_clean()でバッファがクリアされるので意味が無い。
OKパターン3(viewをdisableしちゃう)
$this->response->setContent('abc');
$this->response->send();
$this->view->disable();
return; //=>"abc"(output buffer)
viewを無効化するパターン。この場合はテンプレートエンジンによるレンダリングは行われず、内部ではob_get_contents()によってバッファの内容を取得して表示する。コントローラ内でのecho文等による出力もバッファリングされるので、クリアされずに表示される。
NGパターン(return false+send())
$this->response->setContent('abc');
$this->response->send();
return false; //=>"abcabc"(output buffer + response)
→setContent()の内容が二重に出力される。useImplicitViewがtrueの場合、ob_start()で出力がバッファリングされ、$this->response->sendをすると内部でheader出力やecho出力が行われるが、全てバッファリングされる。return falseを返した場合はスクリプト終了時にバッファの内容がフラッシュされる+echo $application->handle()->getContent()で二重に出力される。つまりreturn falseだとview->finish()を通らないのでバッファリングのクリアを行ってくれないため、send分とecho分が二重に出力される、という感じ。ちなみにreturn falseはviewによるレンダリングは行わないので、OKパターン3のようにview->disable()しても意味が無い。
useImplicitViewがfalseの場合
implictViewがfalseだとob_start等が呼び出されないのでバッファリングが行われない。よって、アプリケーション実行時のecho文はそのまま表示される。上記のパターンはそれぞれ以下のように挙動が変わる。- OKパターン1→テンプレートエンジンではなく、responseオブジェクトの値が反映される
- OKパターン2→responseオブジェクトの値が反映される。
- OKパターン3→二重に出力される。view->disable()の有無は関係なし。
- NGパターン→二重に出力される。
この投稿はPhalcon Advent Calendar 2015の 21日目の記事です。