当我想要生成一个包含javascript函数的json字符串时,我遇到了一个小问题
我使用的是json_encode()
函数,它可以很好地将任何对象/数组编码为json字符串。但是,我想用javascript函数填充一个元素值json_encode()
将始终将我的函数编码为字符串。如何删除"
(报价)?引用"
使我的函数成为一个字符串。这是一个例子:
$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
如何使fnFeedback的值成为一个函数?
首先,您的示例不是合法的JSON语法。假设它是这样的:
var input = '{"status":"oke","fnFeedback":"function (a,b,c){return a+c.FnSource;}"}';
处理此问题的一种方法是正常解析,然后使用eval
将fnFeedback
属性的值转换为Function
对象。然而,使用eval
通常是最后的手段(更不用说,如果您不能完全控制eval
-ed的值,那么风险极高),这里有一种更好的方法,在解析JSON数据时使用一个小技巧。
诀窍是JSON.parse
接受第二个参数,该参数应该是一个接受键/值对并返回结果的函数。这将对解析的每个元素调用。以下是一个将您的序列化函数字符串转换为实际函数的方法:
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;
});
运行时,您可以看到结果:
>result["反馈"]
【功能】
>result['fFeedback'].toString()
'函数匿名(a,b,c){''n返回a+c.FnSource;''n}'
关于这部作品的更详细的解释可以在这里找到(以上内容改编自此)。另一个使用相同想法(我还没有测试过)的(可能更干净的)示例代码的JavaScript要点。
你不能。JSON的意思是:JavaScriptOobjectN旋转。它是一个对象所有属性的String
值的串行化。函数属性不可序列化。如果将JSON字符串反序列化为Object
,则必须将包含该函数的字符串转换为真正的javascript函数(例如,使用eval
或new Function
)。
另请参阅,第5章:
JSON值可以是对象、数组、数字、字符串、true、false或空
JSON不能直接表示函数体。
假设JSON被转换回JS对象(下面称为myObj
),一种可能性是将字符串直接转换为函数,方法是将其封装在括号中(从而将函数声明转换为函数表达式),然后将其传递给eval
:
var fnFeedback = eval('(' + myObj.fnFeedback + ')';
请注意,使用eval
可能存在安全问题——使用时要格外小心,不要信任第三方间接提供的任何功能体。使用Function
更安全,请参阅Ted Hopp稍后的回答。