Using JSON in CakePHP 1.2

May 8th 2008 – Controller::$beforeFilter has been deprecated a while ago, i’ve updated the example using Controller::beforeFilter()
Almost an half year ago I created jsonComponent for CakePHP, since then it has been used by quite a few people including myself.
About 3 months ago I started developing with CakePHP 1.2, one of the projects I’m working on is Pagebakery. Pagebakery relies heavily on AJAX and JSON and it’s therefore a perfect opportunity to experiment with CakePHP’s new features.
One of those features is Router::parseExtensions(). ParseExtensions allows you to parse the extension in your request and let Cake select alternate layouts and views automatically.
Another feature I found is JavascriptHelper::object(), this method is also available in CakePHP 1.1 but I only stumbled on it recently. It’s build-in JSON support in CakePHP, we no longer need the jsonComponent!
I’m going to explain you how to setup CakePHP 1.2 to output JSON with help of Router::parseExtensions() and the JavascriptHelper::object() method.

In this example we’re going to use a simple posts controller like the one in the Cake blog tutorial.
First we need to let Cake know to parse .json extentions. Add the following to /config/routes.php
Router::parseExtensions(’json’);
Because JSON is not a default content type in CakePHP currently, we need to add it. We also need enable the RequestHandler component. Add the following to your app_controller.php
var $components = array(’RequestHandler’);
function beforeFilter() {
$this->RequestHandler->setContent(’json’, ‘text/x-json’);
}
Note: if you use beforeFilter in your controllers you need to call parent::beforeFilter()
Now we need to create our JSON layout.
Create: /layouts/json/default.ctp
Paste the following code in the new layout
< ?php
header("Pragma: no-cache");
header("Cache-Control: no-store, no-cache, max-age=0, must-revalidate");
header('Content-Type: text/x-json');
header("X-JSON: ".$content_for_layout);
echo $content_for_layout;
?>
Note: the X-JSON header is used by prototype.js and is automatically evaluated into a JSON object.
Next is our view, we’ll use the index action of the posts controller.
Create: /views/posts/json/index.ctp
And insert the following code in the view
< ?php
echo $javascript->object($aPosts);
?>
Note: the object method will convert the posts array into a json string, just like the jsonComponent.
Just to be clear here is the index action from the posts controller
function index() {
$this->set(’aPosts’, $this->Post->findAll());
}
Now access your posts controller in your browser, /posts/index/ will output the regular html view and /posts/index.json will output your json object!
Note that you can also use xml, rss (supported by default in CakePHP 1.2) to create your own feed in a snap!
Let me know if you have comments or additions.