CakePHP JSON Response Data in Headers

Posted: December 4th, 2010 | Author: Bret Kuhns | Filed under: Programming, Technology | Tags: , , , , | 1 Comment »

I recently utilized CakePHP’s ability to automatically adjust view parameters based on the requested extension in the URI. This makes it really easy to specify a JSON formatted response by just tacking “.json” to the end of the URI. When I discovered this handy little feature of Cake’s, I was praising the framework for such a quick and useful feature. Until things went wrong, of course.

I do most of my development in Chromium, but noticed when I was testing my code for the new JSON responses, data wasn’t showing up properly in Firefox. I didn’t think much of it and figured I would return to the issue once I could focus on browser compatibility. I eventually, however, found myself at that point in development. I discovered that returning only a sliver of the normal response data lead Firefox to respond properly. I also found Chromium was hitting it’s own, significantly higher, limit. Firefox was capping the JSON response at 4096 bytes, whereas Chromium was somewhere in the area of 305kB. The Chromium limit was practically reasonable for my application, but there was no way I could dodge Firefox’s measly 4kB cap. But wait, there’s no way Firefox limits all AJAX responses to 4kB, right? Gmail can’t possibly operate on an army of tiny 4kB responses, so what am I doing wrong?

Courtesy of Firebug, I compared responses and noticed something peculiar, my server’s JSON responses contained the entire data contents in the headers of the response itself. After some Googling, it seems response header fields have a size limit. In Firefox that limit is, you guessed it, 4096 bytes. As I found, CakePHP’s automatic handling of JSON extensions takes the view variables and places them directly in the headers. Not only that, but my JSON views were returning the json_encode()’ed result of my data, so the response contained the same data in two places. Without much time available for finding a proper way to make Cake stop adding data in the headers, I decided to go back and do it the ol’ fashioned way, by myself. I got rid of Cake’s router line for Router::parseExtensions(‘json’); left my controller action alone, and changed my view to:

<?php
$this->layout = 'ajax';
Configure::write('debug', 0);
header('conten-type:text/x-json');
header('cache-control:no-store,no-cache,max-age=0,must-revalidate');
echo json_encode($results);
?>

And with that, both Firefox and Chromium now accept responses greater than 4kB and 305kB respectively. I’m still sprinting to finish this project, so I haven’t had time to investigate if the core Cake team knows about this issue. I plan to revisit after project launch and see if I can learn more about this strange behavior.


PHP Ternary Reference Assignment

Posted: November 28th, 2010 | Author: Bret Kuhns | Filed under: Programming, Technology | Tags: , | No Comments »

I’m a fan of CakePHP, but some times it can do some goofy things. One such example is the afterFind() Model callback, whose $results parameter may contain data in two different formats depending on how the find results were retrieved elsewhere in the code. This breaks the blackbox concept of functions in which the function shouldn’t care less of what happens outside it’s scope. Because of this oddity, you have to support either the model data existing in the $results array under a key named after the model, or the data existing directly in the $results array as simple key/value pairs. I attempted to make this easy to deal with by doing the following:

$res = ($primary)
	? &$result['MyModel']
	: &$result;

But for whatever reason, PHP fails with an “unexpected &” error after the ternary `?` operator. The ternary syntax is just a shorthand I use for a really easy if-then, so I decided to expand it and see what happens.

if($primary) {
	$res = &$result['MyModel'];
} else {
	$res = &$result;
}

This code runs without a hitch. So then what’s happening? Your guess is as good as mine. I honestly can’t discern what’s making PHP break on the ternary version. Although the ternary syntax is rather simple and can be considered synonymous to the if-then code, PHP seems to handle them differently and consequently breaks reference assignment when using ternary.


PHP Recursive Strings

Posted: November 29th, 2009 | Author: Bret Kuhns | Filed under: Programming | Tags: | 2 Comments »

I needed to construct a recursive string of regular expression patterns. Parts of a string may be built from another string which may also be built of other strings. If you’re familiar, think of production rules in a context-free grammar. If you’re not, then just take for granted this recursive string idea would be useful. I initially decided to build all my patterns into a single array, giving me a nice data collection to access them. I was also under the assumption that my recursive idea would work best with an array as the interpreter would have to account for all strings in the array at once. This would prevent order issues if one string relied on another but wasn’t yet declared. Unfortunately, PHP simply doesn’t seem to work as I had hoped. Read the rest of this entry »