In this post I’ll present a way to send javascript functions over JSON from a php server (but it should work on other platforms too). Since PHP version 5.20 PHP includes the functionsjson_encode()
and json_decode()
. These functions encode values into JSON formatting and decode JSON formatted strings into associative arrays. The json_encode()
function is not able to encode a value into a (javascript) function. This is a common issue when configuring graphs from Flotr (my Javascript plotting library) with JSON data. Here are my findings.
The Problem: Server-side
To get a better feeling for the problem, I’ll show you what happens when we pass an array to json_encode:
// Our sample array $foo = array( 'number' => 1, 'float' => 1.5, 'array' => array(1,2), 'string' => 'bar', 'function'=> 'function(){return "foo bar";}' ); // Now encode the array to JSON format $json = json_encode($foo); // Send to to the client echo $json; ... // This sends the following string to the client: { "number":1, "float":1.5, "array":[1,2], "string":"bar", "function":"function(){return \"foo bar\";}" }
The solution
My solution is very simple:
- Loop over the associative array that is about to be encoded
- Look for values that start with a function definition (like ‘function(‘)
- Remember the value and replace it with a unique key (within the assoc array)
- Encode the changed assoc array to JSON using
json_encode()
- Replace the unique keys enclosed in quotation marks with their original values
- Echo the json string
In PHP:
// Our sample array $foo = array( 'number' => 1, 'float' => 1.5, 'array' => array(1,2), 'string' => 'bar', 'function'=> 'function(){return "foo bar";}' ); $value_arr = array(); $replace_keys = array(); foreach($foo as $key => &$value){ // Look for values starting with 'function(' if(strpos($value, 'function(')===0){ // Store function string. $value_arr[] = $value; // Replace function string in $foo with a 'unique' special key. $value = '%' . $key . '%'; // Later on, we'll look for the value, and replace it. $replace_keys[] = '"' . $value . '"'; } } // Now encode the array to json format $json = json_encode($foo); // $json looks like: { "number":1, "float":1.5, "array":[1,2], "string":"bar", "function":"%function%" } // Replace the special keys with the original string. $json = str_replace($replace_keys, $value_arr, $json); // Send to to the client echo $json; // This echoes the following string: { "number":1, "float":1.5, "array":[1,2], "string":"bar", "function":function(){return "foo bar";} }
Now the ‘function’ key is not a String anymore, but it’s a function. So our problem is solved. When using Prototype, it will look something like this:
new Ajax.Request('json_server.php', { method:'get', onSuccess: function(transport){ var json = transport.responseText.evalJSON(); alert(json.function()); // => alerts 'foo bar' } });
There might be dozens of solutions to the problem stated above, but I couldn’t find ’em on the net. If you know a better technique, please share it!
Source: http://solutoire.com/2008/06/12/sending-javascript-functions-over-json/