3
votes

In my CakePHP app I return JSON and exit for certain requests. An example of this would be trying to access the API for a login as a GET request:

header('Content-Type: application/json');
echo json_encode(array('message'=>'GET request not allowed!'));
exit;

However I am having to prefix the echo with the content type in order for it to be sent as JSON. Otherwise my code at the other end interprets it different.

Any ideas on how to get around this? Or at least improve it.

Update: Cake version 2.3.0

1
This is the correct header for JSON content. There's nothing wrong with prefixing the header to your content. This is how it should be. - Boaz - CorporateShillExchange
Actually, PHP has spoiled you by automatically sending an HTML Content-Type if you don't do so explicitly. So this is indeed how it should be. - Jon
If this bothers you, just create a wrapper function like send_my_json($array) which sends the correct header() then calls json_encode() on the supplied argument. - Michael Berkowski
I wonder why a) you did not mention your cake version (by now you should know that this is vital to get correct answers) and b) you don't use the response object for 2.x (as you probably already know of its existence..) - mark
json's just plain text, so text/plain would be a valid mime type as well. what matters if how the receiving end goes. e.g. jquery can use the mime type to detect json and automatically decide it for you. - Marc B

1 Answers

38
votes

You can leverage the new 2.x response object:

public function youraction() {
    // no view to render
    $this->autoRender = false;
    $this->response->type('json');

    $json = json_encode(array('message'=>'GET request not allowed!'));
    $this->response->body($json);
}

See http://book.cakephp.org/2.0/en/controllers/request-response.html#cakeresponse

Also you could use the powerful rest features and RequestHandlerComponent to achieve this automatically as documented: http://book.cakephp.org/2.0/en/views/json-and-xml-views.html

You just need to allow the extension json and call your action as /controller/action.json. Then cake will automatically use the JsonView and you can just pass your array in. It will be made to JSON and a valid response by the view class.

Both ways are cleaner than your "exit" solution - try to unit-test code that contains die()/exit(). This will end miserably. So better never use it in your code in the first place.