[CakePHP] JSON出力時にstring型をint型に戻す
久々のブログ、今回はCakePHPでJSON出力をするときにInteger型、String型に型変換して出力する方法について書きます。 (あ、今回も他力本願、満載)
まず、CakePHPでJSON出力をする為には
Controllerで
$yourJsonObect= $this->YourModel->find('all'); $this->set('yourJsonObect', $yourJsonObect);
としてやり
Viewで
<?php echo $javascript->object($yourJsonObect); ?>
としてやれば簡単に実現できます。
出力されるコードは以下のようになります。
[{"YourModel":{"id":"10060","foreign_id":"1","short_description":"Short Desc Test.","long_description":"Long Desc Test"}, {} ..... )]
これで、殆ど場合は問題ないのですが、データベース上でIntegerで持っているスキーマ(id, foreign_idなど)も全てString型として出力されます。
もし、JSONデータを受け取る側が厳密にInteger型、String型を区別して受け取りたい場合などに以下の方法でスマートに解決できたので紹介します。
余談ですが、自分の場合は、iPhone開発において、JSONデータをウェブサーバーから受け取り、Core DataにInsertする時に、iPhone側で型チェックや型変換をさせたくなかったので、サーバー側で吸収してしまおうという経緯がありました。
参考にしたサイトはこちらです。
CakePHPのmodelの結果配列でstring型をint型に戻す。
CakePHPでmodel::findなどの関数で結果配列を取得したときに、データベースではint型の値string型として返って来ます。
今回は、flashにjson出力でデータを渡したかったので、別に文字列型のまま渡しても問題ないのかもしれないけど、なんか気持ち悪い。
それに例えばよくある、intの0,1をフラグと扱って if (flag) {.... }なんて書いたらマズいんじゃないかと思うので、settypeで型変換を行う方法。
モデルの親クラスで、Findで取得したデータ(デフォルトは全てString)をデータベースのTypeを参照して、型変換を行っています。
app_model.phpにafterFind()オーバーライド関数を追加してやるだけ。
class AppModel extends Model{ public function afterFind($results, $primary = false) { parent::afterFind($results, $primary); $columnTypes = $this->getColumnTypes(); foreach($results as $index => $result) { foreach($columnTypes as $field => $columnType) { if($columnType == 'integer') { if(isset($results[$index][$this->name][$field])) { settype($results[$index][$this->name][$field], 'integer'); } } } } return $results; } }
これで全てのモデルが自動変換されるようになりました。 感激~
変換後のJSON出力を見ると以下のようになります。
[{"YourModel":{"id":10060,"foreign_id":1,"short_description":"Short Desc Test.","long_description":"Long Desc Test"}, {} ..... )]
Integer型の数字の部分からダブルクォーテーションが消えました。
めでたしめでたし。