2015-12-21

phalconのレスポンスの挙動について調べてみた

今回はphalconのレスポンスの書き方と挙動について書いていきます。サンプルは全てコントローラのアクションメソッド内での処理を想定しています。また、Phalcon\Mvc\ApplicationのuseImplicitViewがtrueの前提で記載していきます。

基本的な挙動

他にも色々あるけど、だいたいこんな感じ。

これを踏まえた上で、OK/NGのパターンは以下のとおり。

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文はそのまま表示される。上記のパターンはそれぞれ以下のように挙動が変わる。  

この投稿はPhalcon Advent Calendar 2015の 21日目の記事です。

このエントリーをはてなブックマークに追加