2010-01-06
cakePHP+ajaxでjsonを扱う
cakePHPとajaxでjsonを扱ってみたのでその備忘録。
まずはコントローラー側で必要なヘルパーとコンポーネントを追加する。
ちなみに view でprototype.js を読み込んでいるがそこは省略w
class HogeController extends AppController {
var $helpers = array("Javascript"); /* 取りあえずは Javascriptヘルパーが必要 */
var $components = array("RequestHandler"); /* RequestHandlerコンポーネントが必要 */
/* コントローラのメソッドなど ... */
}
?
あれ?Ajaxヘルパーは?と思った方もいるだろうけど、AjaxヘルパーはどちらかというとAjaxでリクエストを送ったりする時のものなので、jsonとは直接関係ない。だから、Ajaxヘルパーを使うかどうかはお好みだが、私自身は直接javascriptでAjax.request()メソッドを呼んでいる。(その方が複雑なこともやりやすい)
次に、Ajaxでリクエストを送ってjsonを取得する部分。hogeコントローラーのsampleアクションで実行する。また、jsonデータを取得するアクションをjsonとする。
<?php class HogeController extends AppController { var $helpers = array("Javascript"); /* 取りあえずは Javascriptヘルパーが必要 */ var $components = array("RequestHandler"); /* RequestHandlerコンポーネントが必要 */ function sample() { /* お好きな処理 */ } /* コントローラのメソッドなど ... */ } ?>
sampleアクションのテンプレートで、リンクをクリックすると/hoge/jsonにリクエストされるようにしてみる。
app/views/hoge/sample.ctp
<script type="text/javascript"> window.onload = function() { Event.observe("sample","click",function() { new Ajax.Request( '/hoge/json' , { method: "get" , onSuccess: function (req) { var res; eval("res = "+ req.responseText ); // res.result という値があればalertで表示 if (res.result) { alert(res.result); } } , onFailure: function(req) { alert('読み込みに失敗しました'); }, onException: function (req) { alert('不正な値を取得しました。'); } } ); }); } </script> <a href="javascript:void(0);" id="sample">sample</a>
最後に/hoge/jsonにAjaxでリクエストされたら、jsonデータを返すようにしてみる。
まずはコントローラーのbeforeFilter()でjson用のHTTPヘッダーを出力。beforeFilter()で実行しないと動かなかったので注意。ついでにjsonアクションのメソッドを追加。
<?php class HogeController extends AppController { var $helpers = array("Javascript"); /* 取りあえずは Javascriptヘルパーが必要 */ var $components = array("RequestHandler"); /* RequestHandlerコンポーネントが必要 */ function beforeFilter() { /* お好きな処理 */ // ajax:json の場合 if ($this->RequestHandler->isAjax()) { // action が jsonの場合 if ($this->action === "json") { $this->layout = "ajax"; Configure::write("debug" , 0); $this->RequestHandler->setContent("json"); $this->RequestHandler->respondAs('application/json; charset=UTF-8'); } } } function sample() { /* お好きな処理 */ } function json() { // テンプレートに result 変数をセット $this->set("result" , array("result" => "OK")); } /* コントローラのメソッドなど ... */ } ?>
最後にjsonアクションのviewでjsonデータを出力する。これはjavascriptヘルパーのobject()メソッドで一発でできる。
<?= $javascript->object($result) ?>
以上で、リンクをクリックすると[OK] と表示されます。
こんな感じでPHPの連想配列や配列をそのままjavascriptに渡すことができるので、管理画面などで複雑な処理をする場合に便利です。
ちなみに、Ajaxで後から要素のinnerHTMLを変えると、IE7ではそのinnerHTMLの中の要素にCSSが適応されない、というバグがあったので(もしかしたらケースバイケースかも知れませんが、、)その場合には、jsonでデータを受け取って、javascriptでdomを足していくとうまくいくことが何度かあった。それ以来、面倒なので、Ajaxのデータの受け渡しは基本的にjsonで行うようにしている。
- 2 http://d.hatena.ne.jp/keyword/CakePHP
- 2 http://www.google.co.jp/search?hl=ja&lr=lang_ja&client=firefox-a&rlz=1R1GGGL_ja___JP322&hs=Rb8&ei=GGBES4zEDMugkQW5ydD6Cw&sa=X&oi=spell&resnum=0&ct=result&cd=1&ved=0CAYQBSgA&q=complete+ajax+request+json&spell=1
- 1 http://d.hatena.ne.jp/diarylist
- 1 http://k.hatena.ne.jp/keywordblog/CakePHP?date=20091207
- 1 http://www.google.co.jp/reader/view/
- 1 http://www.google.co.jp/search?hl=ja&q=cake+ajax+view+json&sourceid=navclient-ff&rlz=1B3GGGL_jaJP246JP246&ie=UTF-8
- 1 http://www.google.co.jp/search?hl=ja&q=cakephp+エラーハンドリング+app+controller&btnG=検索&lr=&aq=f&oq=
- 1 http://www.google.co.jp/search?hl=ja&q=cakephp+json&sourceid=navclient-ff&rlz=1B6_____jaJP356JP356&ie=UTF-8
- 1 http://www.google.co.jp/search?hl=ja&q=php+cakephp+エラー制御&btnG=検索&lr=&aq=f&oq=
- 1 http://www.google.co.jp/search?hl=ja&rlz=1B3GGGL_jaJP316JP317&q=cakephp+handleError&btnG=検索&lr=&aq=f&oq=