[Zend Framework] Zend_ControllerアクションヘルパーのContextSwitch
Zend Framework1.5から新しく追加されたContextSwitchアクションヘルパーを使ってみました。
あるページのレスポンス形式をhtmlに加えてrssやatomフィードも追加したいとか、Ajaxで受け取るデータをxmlとjsonの両方に対応したい場合に、新しくactionメソッドを追加したり、処理を複雑にしないで対応することができます。
例として、FooControllerのbarActionメソッドはある画面から非同期通信で呼び出されjson形式でデータを返していたが、あるパラメータが設定されていた場合にXML形式でレスポンスを返すように処理を追加するという処理を考えます。
おそらく私は今までならば以下のように処理をしていたと思います。
public function barAction() { $format = $this->getRequest() ->getQuery('format', "json"); if($format == "xml") { /* XML形式で返す */ // レスポンスヘッダーの設定 $this->getResponse() ->setHeader('Content-Type', 'application/json'); } else { /* JSON形式で返す */ // レスポンスヘッダの設定 $this->getResponse() ->setHeader('Content-Type', 'text/xml'); } // データの取得など ... // データの設定 $this->view->assign($data); // ビューレンダラーのOFF $this->getFrontController() ->setParam('noViewRenderer', true); // データの出力 $this->view->setScriptPath("path/to/view/"); echo $this->view->render($format . '.phtml'); }
おおまかには、
- レスポンスヘッダの設定
- ビューの設定
- (Onになっている場合は)ビューレンダラーのOff
- ビューファイルのパスと、ファイルの設定
という処理を付け加える必要がありました。
ContextSwitchアクションヘルパーを使うことで、ここの処理が自動化されます。
では、ContextSwitchアクションヘルパーの設定をしてみます。ますinit()メソッドで以下のようにアクションヘルパーの初期化をします。
public function init() { $contextSwitch = $this->_helper->getHelper('contextSwitch'); $contextSwitch->addActionContext('bar', 'xml') ->addActionContext('bar', 'json') ->initContext(); }
まずContextSwitchアクションヘルパーのオブジェクトを取得して、addActionContext()でコンテキストの設定を行います。barAction()メソッドに対してxmlとjsonのコンテキストを追加しています。
initContext()で初期化を行って、設定は終わりです。
アクションメソッドではデータの取得など特に処理を変更する必要はありません。
出力する値をアサインしておきます。
public function barAction() { $this->view->bar = "bar"; }
続いてビュースクリプトの設定を行います。
通常デフォルトであれば、ビュースクリプトのファイル名はbar.phmlですが、ContextSwitchアクションヘルパーを使用する場合の拡張子はxml.phtmlやjson.phtmlなど、(コンテキスト名).phtmlとなります。bar.xml.phtmlには以下のように書きます。
< ?xml version="1.0" encoding="UTF-8" ?> <foo> <bar>{$bar}</bar> </foo>
jsonの場合はassign()した値を自動的にjson形式にエンコードしてくれます(ビュースクリプトはなくても大丈夫です)。この設定は以下のようにすることで無効にもすることができます。
$this->_helper->contextSwitch()->setAutoJsonSerialization(false);
この場合はbar.json.phtmlのように、json.phtmlという拡張子のビュースクリプトを準備しておく必要があります。
コンテキストの切り替えは、リクエストパラメータで行います。formatという名前のパラメタにコンテキストのタイプを指定して渡すことで自動的に切り替えてくれます。
http://example.com/foo/bar/?format=xml http://example.com/foo/bar/format/xml
のようにすることでxml形式へコンテクストを切り替えてくれます。
実際に表示させてみると
<foo> <bar>bar</bar> </foo>
レスポンスヘッダにも
Content-Type: text/xml
とちゃんと出ています。json形式へコンテクストを切り替えると、
{"bar":"bar"}レスポンスヘッダには
Content-Type: application/json
と出ました。うまくいったようです。
実はContextSwitchアクションヘルパーがデフォルトで対応しているコンテキストは、xmlとjsonのみです。他の形式をサポートしたい場合は独自で設定を行う必要があります。
尚、Zend_View_Interfaceを実装して独自のviewクラスを使っている場合、コンテキストをjsonでレスポンスを返そうとすると、getVars()がないというエラーが出ます。対応はこちらに書いてありますので参考にしてください。