Reputation: 1863
I have a little problem when I want to generate a json string containing javascript function.
I am using json_encode()
function and it works well for encoding any object/array to be json string. But, I want to fill one of an element value by a javascript function.
json_encode()
will always encode my function to string. How do I can remove the "
(quote)? The quote"
makes my function be a string.
here's the example:
$var['status'] = "oke";
$var['fnFeedback'] = "function (a,b,c){ return a+c.FnSource; }";
echo json_encode($var);
//then the result
{[status:"oke"],[fnFeedback:"function (a,b,c){ return a+c.FnSource; }"]}
//value of fnFeedback of above json is a string
How can I make value of fnFeedback be a function?
Upvotes: 0
Views: 169
Reputation: 339786
JSON cannot directly represent function bodies.
Given your JSON converted back into a JS object (below called myObj
) one possibility is to convert the string directly into a function by wrapping it in parentheses (thus converting the function declaration into a function expression) and then passing it to eval
:
var fnFeedback = eval('(' + myObj.fnFeedback + ')';
Please note that there are possible security issues with using eval
- use with extreme caution and do not trust any function body supplied indirectly by third parties. It's safer to use Function
instead, see Ted Hopp's later answer.
Upvotes: 1
Reputation: 234795
First, your sample isn't legal JSON syntax. Suppose it's something like this instead:
var input = '{"status":"oke","fnFeedback":"function (a,b,c){return a+c.FnSource;}"}';
One way to deal with this is to parse normally and then use eval
to turn the value of the fnFeedback
property into a Function
object. However, using eval
is usually a last resort (not to mention extremely risky if you aren't in total control of the value being eval
-ed) and here there's a better approach using a little trick when parsing JSON data.
The trick is that JSON.parse
accepts a second argument, which should be a function that accepts a key/value pair and returns the result. This will be called for every element that is parsed. Here's one that will turn your serialized function string into an actual function:
var result = JSON.parse(input,
function(key, value) {
// if value looks like a function definition, make a function
if (value
&& typeof value === "string"
&& value.substr(0,8) == "function")
{
var startBody = value.indexOf('{') + 1;
var endBody = value.lastIndexOf('}');
var startArgs = value.indexOf('(') + 1;
var endArgs = value.indexOf(')');
return new Function(value.substring(startArgs, endArgs),
value.substring(startBody, endBody));
}
// else just return the value as is
return value;
});
When this is run, you can then see the results:
> result['fnFeedback']
[Function]
> result['fnFeedback'].toString()
'function anonymous(a,b,c) {\n return a+c.FnSource; \n}'
A more detailed explanation of how this works can be found here (from which the above was adapted). Also see this JavaScript gist for another (perhaps cleaner) sample code using the same idea (which I have not tested).
Upvotes: 2
Reputation: 122908
You can't. JSON means: JavaScript Object Notation. It is a serialisation to String
values of all properties of an Object. Function properties are not serializable. If you deserialize the JSON-string to Object
you'll have to convert the string containing the function to a real javascript function (e.g. using eval
or new Function
).
See also ..., chapter 5:
A JSON value can be an object, array, number, string, true, false, or null
Upvotes: 2