今回は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/NGのパターンは以下のとおり。

OKパターン1(何もreturnしない)

setContentの内容(上記の例だと’abc’)は反映されず、テンプレートエンジンに応じてレスポンスが返される。$this->response->send()を入れたとしても、バッファリングされて、view->finish()内のob_end_clean()によってクリアされるので意味が無い。

OKパターン2(Responseをreturn)

→返却するresponseオブジェクトをベースにレンダリングする。$this->response->send()を入れたとしても、バッファリングされるが、その後、view->finish()内のob_end_clean()でバッファがクリアされるので意味が無い。

OKパターン3(viewをdisableしちゃう)

viewを無効化するパターン。この場合はテンプレートエンジンによるレンダリングは行われず、内部ではob_get_contents()によってバッファの内容を取得して表示する。コントローラ内でのecho文等による出力もバッファリングされるので、クリアされずに表示される。

NGパターン(return false+send())

→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日目の記事です。