简体   繁体   English

PHP json_encode 编码一个 function

[英]PHP json_encode encode a function

How to encode a Javascript function in PHP?如何在 PHP 中编码 Javascript function? I want to encode the callback function with array我想用数组编码回调 function

$options = array(
'title' => 'Title',
'fnCallback' => someCallback);

equivalent ini Javascript:等效 ini Javascript:

var options = {
'title': 'Title',
'fnCallback': someCallback };

I know my PHP code is wrong, how can I fix it?我知道我的 PHP 代码错误,我该如何解决?

Viola i solved my problem with Zend_JSON encoder Viola 我用 Zend_JSON 编码器解决了我的问题

 $options = array(
     'title' => 'Title',
     'fnCallback' => new Zend_Json_Expr('someCallback')
 );      

 Zend_Json::encode(
     $options,
     false,
     array('enableJsonExprFinder' => true));

JSON is for passing values around, they are not suitable for passing pieces of code. JSON 用于传递值,它们不适合传递代码段。

You can, instead, pass a function name or other meaningful value and retrieve the right function to call from it on the JavaScript side.相反,您可以传递 function 名称或其他有意义的值并检索正确的 function 以在 JavaScript 端调用它。

To make the notice go away in PHP, just write your callback function in quotes:要在 PHP 中通知 go,只需将回调 function 写在引号中:

$options = array(
   'title' => 'Title',
   'fnCallback' => "someCallback");

And then when you receive the JSON in Javascript, you can remap the callback function name to the actual JS function with eg: And then when you receive the JSON in Javascript, you can remap the callback function name to the actual JS function with eg:

json = $.getJSON(..);
json.fnCallback = window[json.fnCallback];   // for global callbacks

Voici le code que j'utilise pour faire cela: Voici le code que j'utilise pour faire cela:

//~ [FUNCTION]
function __json_encode($mVar,$fnCallback="stripcslashes") {
    return preg_replace_callback('#"[ ]{0,}function[ ]{0,}\([^)$]{0,}\)[ ]{0,}\{[ ]{0,}(?(?![ ]{0,}}[ ]{0,}").){0,}[ ]{0,}\}[ ]{0,}"([(?,")|(?\}{0,}$)]{0,})#si', 
        function ($aRes) use ($fnCallback) { 
            for($aRes[0]=substr($aRes[0],1),$sOut="",$i=0,$iOpen=0,$iClose=0;$i<= strlen($aRes[0]) && $sOut.= substr($aRes[0],$i,1);$i++) 
                if (substr($aRes[0],$i,1) == "{") $iOpen++;
                else if (substr($aRes[0],$i,1) == "}" AND $iOpen == ++$iClose) break;
            return is_callable($fnCallback) ? $fnCallback($sOut).$aRes[1] : $sOut.$aRes[1]; 
        },json_encode($mVar)
    );
}



//~ [TEST]
print "<script>\n";
print sprintf(
    "\tvar oTest = %s;",
    __json_encode(
        array( 
            "Numeric"=>1,
            "string"=>"hello world !",
            "myFunction"=>"function(test) {  if (test==1) { alert('myFunction(1)'); return true; } else return false; }",
            "myObject"=>array(
                "Numeric"=>1,
                "string"=>"hello world !",
                "myFunction"=>"function(test) {  alert('myFunction(1)'); return true; }")
        )
    )
);
print "\n\tif (oTest.myFunction(1) == false) alert('myFunction(0)');";
print "\n\tif (oTest.myObject.myFunction(0) == false) alert('myFunction(0)');";
print "\n</script>";

Voici le résultat:结果的声音:

    <script>
        var oTest = {
            "Numeric":1,
            "string":"hello world !",
            "myFunction":function(test) {  if (test==1) { alert('myFunction(1)'); return true; } else return false; },
            "myObject":{
                "Numeric":1,
                "string":"hello world !",
                "myFunction":function(test) {  alert('myFunction(1)'); return true; }
            }
        };
        if (oTest.myFunction(0) == false) alert('myFunction(0)');
        if (oTest.myObject.myFunction(1) == false) alert('myFunction(0)');
    </script>

Cdt.镉。

Don't confuse JSON for actual, native, Javascript object notation syntax (regardless of the name).不要将 JSON 与实际的、本机的 Javascript object 表示法语法(无论名称如何)混淆。 Javascript objects can contain function references; Javascript 对象可以包含 function 引用; JSON cannot. JSON 不能。

That is not possible without thinking of a convention and implementing it yourself.如果不考虑约定并自己实施,这是不可能的。

Say, you have this JSON说,你有这个 JSON

'{"title": "Title", "fnCallback": "someCallback" }'

Then you could do, on the client side然后你可以在客户端做

function wireupCallbacks(jsonObject) {
  if (typeof jsonObject === "object") {
    for (var prop in jsonObject) {
      var callbackName = jsonObject[prop];
      if (/Callback$/.test(prop) && typeof callbackName === "string") {
        if (typeof this[callbackName] === "function") {
          jsonObject[prop] = this[callbackName];
        }
      }
    }
  }
  return jsonObject;
}

and call that in the context of an object that provides your callback functions并在提供回调函数的 object 的上下文中调用它

var someObject = {
  someCallback: function() { alert("It works!"); }
}

var jsonObject = {"title": "Title", "fnCallback": "someCallback" };

wireupCallbacks.call(someObject, jsonObject);

jsonObject.fnCallback(); // alerts "It works!"

What's missing:少了什么东西:

  • currently the function only looks for properties named "*Callback" .目前 function 仅查找名为"*Callback"的属性。
  • there is no fallback to global functions (these would be properties of the window object)没有回退到全局函数(这些将是window对象的属性)
  • there is no recursion (nested objects are not visited)没有递归(不访问嵌套对象)
  • there is no JSON array handling没有 JSON 阵列处理

Add these features on your own, none of these should be difficult to implement.自己添加这些功能,这些都应该不难实现。

I liked the idea in this comment , so I expanded upon it.我喜欢这个评论中的想法,所以我扩展了它。

This uses a unique ID for the replacement, so that it's unlikely to have any character conflicts or accidental replacements.这使用唯一 ID 进行替换,因此不太可能出现任何字符冲突或意外替换。 You could alternatively use a GUID .您也可以使用GUID

  $callback_uuid = uniqid();
  $config = [
    'foo' => 'bar',
    'callback' => $callback_uuid,
  ];

  $json = json_encode($config, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT);

  // Replace UUID with JS function, and remove the surrounding quotations.
  // Note: This avoids putting '$0' in the string, because regexes replace that.
  $callback_js = "function(value){return'$'+value+(value?'K':'');}";
  $json = preg_replace("/\"$callback_uuid\"/", $callback_js, $json);

As an alternative, if you need to put the JSON into a URL and simply need a nice way to define the JS prior to encoding it, you can use a Heredoc string :作为替代方案,如果您需要将 JSON 放入 URL 并且只需要一种在编码之前定义 JS 的好方法,您可以使用Heredoc 字符串

  $config = <<<EOF
    {
      foo: "bar",
      callback: function(value){return'$'+value+(value?'K':'');}
    }
  EOF;

You forgot the comma between 'title' and 'fnCallback.'您忘记了“title”和“fnCallback”之间的逗号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM