Jacob Steringa

Thoughts on web development

Posts tagged php

20 notes &

Content-type mapping with Lithium

Recently I started experimenting with Lithium, an awesome PHP framework. I really like it’s style, as it uses many new features of PHP 5.3 which really can make your code a lot leaner.

I wanted to return JSON in some occasions and Lithium has a neat feature on collections where you can call ->to(‘json’) on an result set. It works out of the box, but there is a problem with the formatting of the JSON. It looks like this:

{"1":{"id":"1","family_id":"2","family_position":"0","na....},{"id":"2","fami....}}

As you see, it is an object with objects in it. The desired result in my case is an array of objects, like this:

[{"id":"1","family_id":"2","family_position":"0","na....},{"id":"2","fami....}]

I started looking around the interwebs to find a solution. But I didn’t find a satisfying answer in the Li3 manual, so I started to browse the API docs. The docs for the Media class, the class responsible for almost everything what has to do with content-types, gave me the answer right away.

Within the file config/bootstrap/media.php you can declare custom content-types and assign custom handlers. With that knowledge things got really easy. I knew that I could get the desired result if I manually altered the results in the controller, but that doesn’t really adhere to the DRY principle. Declaring my own handler for the JSON format was the solution.

Media::type('json', 'application/json', array(
	'encode' => function($data) {
		$result = array();
		
		foreach($data as $object) {
			$result[] = $object;
		}
		
		return json_encode($result);
	}
));

This small snippet fixed my problem! I can now render JSON like this:

$this->render(array('json' => Projects::all()));

The cool thing about this feature is that it works for many more content-types, for instance csv, like in the example in the Li3 API docs.

Filed under php json